--- a/.hgtags Tue Jul 16 17:00:00 2019 -0700
+++ b/.hgtags Mon Jul 22 11:08:27 2019 +0530
@@ -569,3 +569,8 @@
43627549a488b7d0b4df8fad436e36233df89877 jdk-14+2
b7f68ddec66f996ae3aad03291d129ca9f02482d jdk-13+27
e64383344f144217c36196c3c8a2df8f588a2af3 jdk-14+3
+1e95931e7d8fa7e3899340a9c7cb28dbea50c10c jdk-13+28
+19d0b382f0869f72d4381b54fa129f1c74b6e766 jdk-14+4
+3081f39a3d30d63b112098386ac2bb027c2b7223 jdk-13+29
+0f1e29c77e50c7da11d83df410026392c4d1a28c jdk-14+5
+443f7359b34d60e7821216ffc60f88b6ffe0ccdd jdk-14+6
--- a/make/Docs.gmk Tue Jul 16 17:00:00 2019 -0700
+++ b/make/Docs.gmk Mon Jul 22 11:08:27 2019 +0530
@@ -553,7 +553,7 @@
$(eval specs_bottom_rel_path := $(specs_bottom_rel_path)../) \
)
-SPECS_TOP := $(if $(filter true, $(IS_DRAFT)), <div class="draft-header">$(DRAFT_TEXT)</div>)
+SPECS_TOP := $(if $(filter true, $(IS_DRAFT)), <header class="draft-header">$(DRAFT_TEXT)</header>)
# For all html files in $module/share/specs directories, copy and add the
# copyright footer.
@@ -595,7 +595,9 @@
DEST := $(DOCS_OUTPUTDIR)/specs/, \
CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \
OPTIONS := -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_$($m_$f_NOF_SUBDIRS))', \
- REPLACEMENTS := @@VERSION_STRING@@ => $(VERSION_STRING), \
+ REPLACEMENTS := \
+ @@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \
+ @@VERSION_STRING@@ => $(VERSION_STRING), \
POST_PROCESS := $(TOOL_FIXUPPANDOC), \
)) \
$(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
@@ -625,8 +627,11 @@
DEST := $(DOCS_OUTPUTDIR)/specs/man, \
FILTER := $(PANDOC_HTML_MANPAGE_FILTER), \
CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \
- REPLACEMENTS := @@VERSION_SHORT@@ => $(VERSION_SHORT), \
- OPTIONS := -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_1)', \
+ REPLACEMENTS := \
+ @@COPYRIGHT_YEAR@@ => $(COPYRIGHT_YEAR) ; \
+ @@VERSION_SHORT@@ => $(VERSION_SHORT) ; \
+ @@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION), \
+ OPTIONS := --toc -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_1)', \
POST_PROCESS := $(TOOL_FIXUPPANDOC), \
EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
$(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT), \
--- a/make/Images.gmk Tue Jul 16 17:00:00 2019 -0700
+++ b/make/Images.gmk Mon Jul 22 11:08:27 2019 +0530
@@ -102,7 +102,7 @@
WARN := Creating legacy jre image, \
DEPS := $(JMODS) $(BASE_RELEASE_FILE) \
$(call DependOnVariable, JDK_MODULES_LIST), \
- OUTPUT_DIR := $(JDK_IMAGE_DIR), \
+ OUTPUT_DIR := $(JRE_IMAGE_DIR), \
SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \
PRE_COMMAND := $(RM) -r $(JRE_IMAGE_DIR), \
COMMAND := $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
@@ -138,7 +138,7 @@
-Xmx128M -Xms128M $(LOG_INFO), \
))
- JDK_TARGETS += $(gen_cds_archive_jdk)
+ JRE_TARGETS += $(gen_cds_archive_jre)
endif
################################################################################
--- a/make/InitSupport.gmk Tue Jul 16 17:00:00 2019 -0700
+++ b/make/InitSupport.gmk Mon Jul 22 11:08:27 2019 +0530
@@ -424,8 +424,8 @@
$(if $(filter all, $(LOG_REPORT)), \
$(GREP) -v -e "^Note: including file:" < $(logfile) || true $(NEWLINE) \
, \
- ($(GREP) -v -e "^Note: including file:" < $(logfile) || true) | $(HEAD) -n 12 $(NEWLINE) \
- if test `$(WC) -l < $(logfile)` -gt 12; then \
+ ($(GREP) -v -e "^Note: including file:" < $(logfile) || true) | $(HEAD) -n 15 $(NEWLINE) \
+ if test `$(WC) -l < $(logfile)` -gt 15; then \
$(ECHO) " ... (rest of output omitted)" ; \
fi $(NEWLINE) \
) \
--- a/make/autoconf/flags-cflags.m4 Tue Jul 16 17:00:00 2019 -0700
+++ b/make/autoconf/flags-cflags.m4 Mon Jul 22 11:08:27 2019 +0530
@@ -576,10 +576,10 @@
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
# Suggested additions: -qsrcmsg to get improved error reporting
- TOOLCHAIN_CFLAGS_JDK="-qchars=signed -qfullpath -qsaveopt -qstackprotect" # add on both CFLAGS
- TOOLCHAIN_CFLAGS_JVM="-qtune=balanced \
- -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
- -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno -qstackprotect"
+ # set -qtbtable=full for a better traceback table/better stacks in hs_err when xlc16 is used
+ TOOLCHAIN_CFLAGS_JDK="-qtbtable=full -qchars=signed -qfullpath -qsaveopt -qstackprotect" # add on both CFLAGS
+ TOOLCHAIN_CFLAGS_JVM="-qtbtable=full -qtune=balanced \
+ -qalias=noansi -qstrict -qtls=default -qnortti -qnoeh -qignerrno -qstackprotect"
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
TOOLCHAIN_CFLAGS_JVM="-nologo -MD -MP"
TOOLCHAIN_CFLAGS_JDK="-nologo -MD -Zc:wchar_t-"
--- a/make/autoconf/flags.m4 Tue Jul 16 17:00:00 2019 -0700
+++ b/make/autoconf/flags.m4 Mon Jul 22 11:08:27 2019 +0530
@@ -176,6 +176,10 @@
AC_MSG_WARN([Ignoring LDFLAGS($LDFLAGS) found in environment. Use --with-extra-ldflags])
fi
+ if test "x$ASFLAGS" != "x"; then
+ AC_MSG_WARN([Ignoring ASFLAGS($ASFLAGS) found in environment. Use --with-extra-asflags])
+ fi
+
AC_ARG_WITH(extra-cflags, [AS_HELP_STRING([--with-extra-cflags],
[extra flags to be used when compiling jdk c-files])])
@@ -185,9 +189,13 @@
AC_ARG_WITH(extra-ldflags, [AS_HELP_STRING([--with-extra-ldflags],
[extra flags to be used when linking jdk])])
+ AC_ARG_WITH(extra-asflags, [AS_HELP_STRING([--with-extra-asflags],
+ [extra flags to be passed to the assembler])])
+
USER_CFLAGS="$with_extra_cflags"
USER_CXXFLAGS="$with_extra_cxxflags"
USER_LDFLAGS="$with_extra_ldflags"
+ USER_ASFLAGS="$with_extra_asflags"
])
# Setup the sysroot flags and add them to global CFLAGS and LDFLAGS so
@@ -280,10 +288,12 @@
EXTRA_CFLAGS="$MACHINE_FLAG $USER_CFLAGS"
EXTRA_CXXFLAGS="$MACHINE_FLAG $USER_CXXFLAGS"
EXTRA_LDFLAGS="$MACHINE_FLAG $USER_LDFLAGS"
+ EXTRA_ASFLAGS="$USER_ASFLAGS"
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(EXTRA_CXXFLAGS)
AC_SUBST(EXTRA_LDFLAGS)
+ AC_SUBST(EXTRA_ASFLAGS)
# For autoconf testing to work, the global flags must also be stored in the
# "unnamed" CFLAGS etc.
--- a/make/autoconf/spec.gmk.in Tue Jul 16 17:00:00 2019 -0700
+++ b/make/autoconf/spec.gmk.in Mon Jul 22 11:08:27 2019 +0530
@@ -489,6 +489,7 @@
EXTRA_CFLAGS = @EXTRA_CFLAGS@
EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
+EXTRA_ASFLAGS = @EXTRA_ASFLAGS@
CXX:=@FIXPATH@ @CCACHE@ @ICECC@ @CXX@
--- a/make/data/docs-resources/resources/jdk-default.css Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/docs-resources/resources/jdk-default.css Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,6 +85,8 @@
margin-top: -1em;
}
+a { text-decoration: none }
+
a:link {
color: #4A6782;
}
@@ -162,3 +164,22 @@
font-style: italic;
font-size: 80%;
}
+
+nav#TOC {
+ border: 1px solid gray;
+ border-radius: 10px;
+ padding: 5px 10px;
+ margin-bottom: 15px;
+}
+
+nav#TOC ul ul {
+ font-size:smaller;
+}
+
+nav#TOC ul ul li {
+ display: inline-block
+}
+
+nav#TOC ul ul li::before {
+ content: " \2022 "
+}
--- a/make/data/tzdata/VERSION Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/VERSION Mon Jul 22 11:08:27 2019 +0530
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2018g
+tzdata2019a
--- a/make/data/tzdata/africa Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/africa Mon Jul 22 11:08:27 2019 +0530
@@ -387,6 +387,11 @@
# See Africa/Lagos.
# Eritrea
+# See Africa/Nairobi.
+
+# Eswatini (formerly Swaziland)
+# See Africa/Johannesburg.
+
# Ethiopia
# See Africa/Nairobi.
#
@@ -870,8 +875,41 @@
# From Mohamed Essedik Najd (2018-10-26):
# Today, a Moroccan government council approved the perpetual addition
# of 60 minutes to the regular Moroccan timezone.
-# From Brian Inglis (2018-10-26):
-# http://www.maroc.ma/fr/actualites/le-conseil-de-gouvernement-adopte-un-projet-de-decret-relatif-lheure-legale-stipulant-le
+# From Matt Johnson (2018-10-28):
+# http://www.sgg.gov.ma/Portals/1/BO/2018/BO_6720-bis_Ar.pdf
+#
+# From Maamar Abdelkader (2018-11-01):
+# We usually move clocks back the previous week end and come back to the +1
+# the week end after.... The government does not announce yet the decision
+# about this temporary change. But it s 99% sure that it will be the case,
+# as in previous years. An unofficial survey was done these days, showing
+# that 64% of asked peopke are ok for moving from +1 to +0 during Ramadan.
+# https://leconomiste.com/article/1035870-enquete-l-economiste-sunergia-64-des-marocains-plebiscitent-le-gmt-pendant-ramadan
+#
+# From Paul Eggert (2018-11-01):
+# For now, guess that Morocco will fall back at 03:00 the last Sunday
+# before Ramadan, and spring forward at 02:00 the first Sunday after
+# Ramadan, as this has been the practice since 2012. To implement this,
+# transition dates for 2019 through 2037 were determined by running the
+# following program under GNU Emacs 26.1.
+# (let ((islamic-year 1440))
+# (require 'cal-islam)
+# (while (< islamic-year 1460)
+# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
+# (b (calendar-islamic-to-absolute (list 10 1 islamic-year)))
+# (sunday 0))
+# (while (/= sunday (mod (setq a (1- a)) 7)))
+# (while (/= sunday (mod b 7))
+# (setq b (1+ b)))
+# (setq a (calendar-gregorian-from-absolute a))
+# (setq b (calendar-gregorian-from-absolute b))
+# (insert
+# (format
+# (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 3:00\t-1:00\t-\n"
+# "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 2:00\t0\t-\n")
+# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
+# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
+# (setq islamic-year (+ 1 islamic-year))))
# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Morocco 1939 only - Sep 12 0:00 1:00 -
@@ -903,7 +941,7 @@
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2013 only - Jul 7 3:00 0 -
Rule Morocco 2013 only - Aug 10 2:00 1:00 -
-Rule Morocco 2013 2018 - Oct lastSun 3:00 0 -
+Rule Morocco 2013 2017 - Oct lastSun 3:00 0 -
Rule Morocco 2014 2018 - Mar lastSun 2:00 1:00 -
Rule Morocco 2014 only - Jun 28 3:00 0 -
Rule Morocco 2014 only - Aug 2 2:00 1:00 -
@@ -915,13 +953,53 @@
Rule Morocco 2017 only - Jul 2 2:00 1:00 -
Rule Morocco 2018 only - May 13 3:00 0 -
Rule Morocco 2018 only - Jun 17 2:00 1:00 -
+Rule Morocco 2019 only - May 5 3:00 0 -
+Rule Morocco 2019 only - Jun 9 2:00 1:00 -
+Rule Morocco 2020 only - Apr 19 3:00 0 -
+Rule Morocco 2020 only - May 24 2:00 1:00 -
+Rule Morocco 2021 only - Apr 11 3:00 0 -
+Rule Morocco 2021 only - May 16 2:00 1:00 -
+Rule Morocco 2022 only - Mar 27 3:00 0 -
+Rule Morocco 2022 only - May 8 2:00 1:00 -
+Rule Morocco 2023 only - Mar 19 3:00 0 -
+Rule Morocco 2023 only - Apr 23 2:00 1:00 -
+Rule Morocco 2024 only - Mar 10 3:00 0 -
+Rule Morocco 2024 only - Apr 14 2:00 1:00 -
+Rule Morocco 2025 only - Feb 23 3:00 0 -
+Rule Morocco 2025 only - Apr 6 2:00 1:00 -
+Rule Morocco 2026 only - Feb 15 3:00 0 -
+Rule Morocco 2026 only - Mar 22 2:00 1:00 -
+Rule Morocco 2027 only - Feb 7 3:00 0 -
+Rule Morocco 2027 only - Mar 14 2:00 1:00 -
+Rule Morocco 2028 only - Jan 23 3:00 0 -
+Rule Morocco 2028 only - Feb 27 2:00 1:00 -
+Rule Morocco 2029 only - Jan 14 3:00 0 -
+Rule Morocco 2029 only - Feb 18 2:00 1:00 -
+Rule Morocco 2029 only - Dec 30 3:00 0 -
+Rule Morocco 2030 only - Feb 10 2:00 1:00 -
+Rule Morocco 2030 only - Dec 22 3:00 0 -
+Rule Morocco 2031 only - Jan 26 2:00 1:00 -
+Rule Morocco 2031 only - Dec 14 3:00 0 -
+Rule Morocco 2032 only - Jan 18 2:00 1:00 -
+Rule Morocco 2032 only - Nov 28 3:00 0 -
+Rule Morocco 2033 only - Jan 9 2:00 1:00 -
+Rule Morocco 2033 only - Nov 20 3:00 0 -
+Rule Morocco 2033 only - Dec 25 2:00 1:00 -
+Rule Morocco 2034 only - Nov 5 3:00 0 -
+Rule Morocco 2034 only - Dec 17 2:00 1:00 -
+Rule Morocco 2035 only - Oct 28 3:00 0 -
+Rule Morocco 2035 only - Dec 2 2:00 1:00 -
+Rule Morocco 2036 only - Oct 19 3:00 0 -
+Rule Morocco 2036 only - Nov 23 2:00 1:00 -
+Rule Morocco 2037 only - Oct 4 3:00 0 -
+Rule Morocco 2037 only - Nov 15 2:00 1:00 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
0:00 Morocco +00/+01 1984 Mar 16
1:00 - +01 1986
- 0:00 Morocco +00/+01 2018 Oct 27
- 1:00 - +01
+ 0:00 Morocco +00/+01 2018 Oct 28 3:00
+ 0:00 Morocco +00/+01
# Western Sahara
#
@@ -936,8 +1014,8 @@
Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El Aaiún
-1:00 - -01 1976 Apr 14
- 0:00 Morocco +00/+01 2018 Oct 27
- 1:00 - +01
+ 0:00 Morocco +00/+01 2018 Oct 28 3:00
+ 0:00 Morocco +00/+01
# Mozambique
#
@@ -1094,10 +1172,20 @@
# the switch is from 01:00 to 02:00 ... [Decree No. 25/2017]
# http://www.mnec.gov.st/index.php/publicacoes/documentos/file/90-decreto-lei-n-25-2017
+# From Vadim Nasardinov (2018-12-29):
+# São Tomé and Príncipe is about to do the following on Jan 1, 2019:
+# https://www.stp-press.st/2018/12/05/governo-jesus-ja-decidiu-repor-hora-legal-sao-tomense/
+#
+# From Michael Deckers (2018-12-30):
+# https://www.legis-palop.org/download.jsp?idFile=102818
+# ... [The legal time of the country, which coincides with universal
+# coordinated time, will be restituted at 2 o'clock on day 1 of January, 2019.]
+
Zone Africa/Sao_Tome 0:26:56 - LMT 1884
-0:36:45 - LMT 1912 Jan 1 00:00u # Lisbon MT
0:00 - GMT 2018 Jan 1 01:00
- 1:00 - WAT
+ 1:00 - WAT 2019 Jan 1 02:00
+ 0:00 - GMT
# Senegal
# See Africa/Abidjan.
@@ -1128,7 +1216,7 @@
1:30 - SAST 1903 Mar
2:00 SA SAST
Link Africa/Johannesburg Africa/Maseru # Lesotho
-Link Africa/Johannesburg Africa/Mbabane # Swaziland
+Link Africa/Johannesburg Africa/Mbabane # Eswatini
#
# Marion and Prince Edward Is
# scientific station since 1947
@@ -1170,9 +1258,6 @@
2:00 Sudan CA%sT 2000 Jan 15 12:00
3:00 - EAT
-# Swaziland
-# See Africa/Johannesburg.
-
# Tanzania
# See Africa/Nairobi.
--- a/make/data/tzdata/asia Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/asia Mon Jul 22 11:08:27 2019 +0530
@@ -609,12 +609,82 @@
# obtained from
# http://www.hko.gov.hk/gts/time/Summertime.htm
-# From Arthur David Olson (2009-10-28):
+# From Phake Nick (2018-10-27):
+# According to Singaporean newspaper
+# http://eresources.nlb.gov.sg/newspapers/Digitised/Article/singfreepresswk19041102-1.2.37
+# the day that Hong Kong start using GMT+8 should be Oct 30, 1904.
+#
+# From Paul Eggert (2018-11-17):
+# Hong Kong had a time ball near the Marine Police Station, Tsim Sha Tsui.
+# "The ball was raised manually each day and dropped at exactly 1pm
+# (except on Sundays and Government holidays)."
+# Dyson AD. From Time Ball to Atomic Clock. Hong Kong Government. 1983.
+# <https://www.hko.gov.hk/publica/gen_pub/timeball_atomic_clock.pdf>
+# "From 1904 October 30 the time-ball at Hong Kong has been dropped by order
+# of the Governor of the Colony at 17h 0m 0s G.M.T., which is 23m 18s.14 in
+# advance of 1h 0m 0s of Hong Kong mean time."
+# Hollis HP. Universal Time, Longitudes, and Geodesy. Mon Not R Astron Soc.
+# 1905-02-10;65(4):405-6. https://doi.org/10.1093/mnras/65.4.382
+#
+# From Joseph Myers (2018-11-18):
+# An astronomer before 1925 referring to GMT would have been using the old
+# astronomical convention where the day started at noon, not midnight.
+#
+# From Steve Allen (2018-11-17):
+# Meteorological Observations made at the Hongkong Observatory in the year 1904
+# page 4 <https://books.google.com/books?id=kgw5AQAAMAAJ&pg=RA4-PA4>
+# ... the log of drop times in Table II shows that on Sunday 1904-10-30 the
+# ball was dropped. So that looks like a special case drop for the sake
+# of broadcasting the new local time.
+#
+# From Phake Nick (2018-11-18):
+# According to The Hong Kong Weekly Press, 1904-10-29, p.324, the
+# governor of Hong Kong at the time stated that "We are further desired to
+# make it known that the change will be effected by firing the gun and by the
+# dropping of the Ball at 23min. 18sec. before one."
+# From Paul Eggert (2018-11-18):
+# See <https://mmis.hkpl.gov.hk> for this; unfortunately Flash is required.
+
+# From Phake Nick (2018-10-26):
+# I went to check microfilm records stored at Hong Kong Public Library....
+# on September 30 1941, according to Ta Kung Pao (Hong Kong edition), it was
+# stated that fallback would occur on the next day (the 1st)'s "03:00 am (Hong
+# Kong Time 04:00 am)" and the clock will fall back for a half hour. (03:00
+# probably refer to the time commonly used in mainland China at the time given
+# the paper's background) ... the sunrise/sunset time given by South China
+# Morning Post for October 1st was indeed moved by half an hour compares to
+# before. After that, in December, the battle to capture Hong Kong started and
+# the library doesn't seems to have any record stored about press during that
+# period of time. Some media resumed publication soon after that within the
+# same month, but there were not much information about time there. Later they
+# started including a radio program guide when they restored radio service,
+# explicitly mentioning it use Tokyo standard time, and later added a note
+# saying it's half an hour ahead of the old Hong Kong standard time, and it
+# also seems to indicate that Hong Kong was not using GMT+8 when it was
+# captured by Japan.
+#
+# Image of related sections on newspaper:
+# * 1941-09-30, Ta Kung Pao (Hong Kong), "Winter Time start tomorrow".
+# https://i.imgur.com/6waY51Z.jpg (Chinese)
+# * 1941-09-29, South China Morning Post, Information on sunrise/sunset
+# time and other things for September 30 and October 1.
+# https://i.imgur.com/kCiUR78.jpg
+# * 1942-02-05. The Hong Kong News, Radio Program Guide.
+# https://i.imgur.com/eVvDMzS.jpg
+# * 1941-06-14. Hong Kong Daily Press, Daylight Saving from 3am Tomorrow.
+# https://i.imgur.com/05KkvtC.png
+# * 1941-09-30, Hong Kong Daily Press, Winter Time Warning.
+# https://i.imgur.com/dge4kFJ.png
+# Also, the Liberation day of Hong Kong after WWII which British rule
+# over the territory resumed was August 30, 1945, which I think should
+# be the termination date for the use of JST in the territory....
+
+# From Paul Eggert (2018-11-17):
# Here are the dates given at
-# http://www.hko.gov.hk/gts/time/Summertime.htm
-# as of 2009-10-28:
+# https://www.hko.gov.hk/gts/time/Summertime.htm
+# as of 2014-06-19:
# Year Period
-# 1941 1 Apr to 30 Sep
+# 1941 15 Jun to 30 Sep
# 1942 Whole year
# 1943 Whole year
# 1944 Whole year
@@ -625,7 +695,7 @@
# 1949 3 Apr to 30 Oct
# 1950 2 Apr to 29 Oct
# 1951 1 Apr to 28 Oct
-# 1952 6 Apr to 25 Oct
+# 1952 6 Apr to 2 Nov
# 1953 5 Apr to 1 Nov
# 1954 21 Mar to 31 Oct
# 1955 20 Mar to 6 Nov
@@ -654,25 +724,25 @@
# 1978 Nil
# 1979 13 May to 21 Oct
# 1980 to Now Nil
-# The page does not give start or end times of day.
-# The page does not give a start date for 1942.
-# The page does not givw an end date for 1945.
-# The Japanese occupation of Hong Kong began on 1941-12-25.
-# The Japanese surrender of Hong Kong was signed 1945-09-15.
-# For lack of anything better, use start of those days as the transition times.
+# The page does not give times of day for transitions,
+# or dates for the 1942 and 1945 transitions.
+# The Japanese occupation of Hong Kong began 1941-12-25.
+# The Japanese surrender of Hong Kong was signed 1945-09-16; see:
+# Heaver S. The days after the Pacific war ended: unsettling times
+# in Hong Kong. Post Magazine. 2016-06-13.
+# https://www.scmp.com/magazines/post-magazine/article/1852990/days-after-pacific-war-ended-unsettling-times-hong-kong
+# For lack of anything better, use start of those days as the
+# transition times.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule HK 1941 only - Apr 1 3:30 1:00 S
-Rule HK 1941 only - Sep 30 3:30 0 -
Rule HK 1946 only - Apr 20 3:30 1:00 S
Rule HK 1946 only - Dec 1 3:30 0 -
Rule HK 1947 only - Apr 13 3:30 1:00 S
Rule HK 1947 only - Dec 30 3:30 0 -
Rule HK 1948 only - May 2 3:30 1:00 S
Rule HK 1948 1951 - Oct lastSun 3:30 0 -
-Rule HK 1952 only - Oct 25 3:30 0 -
+Rule HK 1952 1953 - Nov Sun>=1 3:30 0 -
Rule HK 1949 1953 - Apr Sun>=1 3:30 1:00 S
-Rule HK 1953 only - Nov 1 3:30 0 -
Rule HK 1954 1964 - Mar Sun>=18 3:30 1:00 S
Rule HK 1954 only - Oct 31 3:30 0 -
Rule HK 1955 1964 - Nov Sun>=1 3:30 0 -
@@ -682,9 +752,11 @@
Rule HK 1979 only - May Sun>=8 3:30 1:00 S
Rule HK 1979 only - Oct Sun>=16 3:30 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30
- 8:00 HK HK%sT 1941 Dec 25
- 9:00 - JST 1945 Sep 15
+Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 0:36:42
+ 8:00 - HKT 1941 Jun 15 3:30
+ 8:00 1:00 HKST 1941 Oct 1 4:00
+ 8:30 - HKT 1941 Dec 25
+ 9:00 - JST 1945 Sep 16
8:00 HK HK%sT
###############################################################################
@@ -1080,6 +1152,16 @@
# India
+# British astronomer Henry Park Hollis disliked India Standard Time's offset:
+# "A new time system has been proposed for India, Further India, and Burmah.
+# The scheme suggested is that the times of the meridians 5½ and 6½ hours
+# east of Greenwich should be adopted in these territories. No reason is
+# given why hourly meridians five hours and six hours east should not be
+# chosen; a plan which would bring the time of India into harmony with
+# that of almost the whole of the civilised world."
+# Hollis HP. Universal Time, Longitudes, and Geodesy. Mon Not R Astron Soc.
+# 1905-02-10;65(4):405-6. https://doi.org/10.1093/mnras/65.4.382
+
# From Ian P. Beacock, in "A brief history of (modern) time", The Atlantic
# https://www.theatlantic.com/technology/archive/2015/12/the-creation-of-modern-time/421419/
# (2015-12-22):
@@ -1250,12 +1332,65 @@
# leap year calculation involved. There has never been any serious
# plan to change that law....
#
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2018-11-30):
# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
-# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
-# stopping after 2037 when 32-bit time_t's overflow.
-# That cal-persia used Birashk's approximation, which disagrees with the solar
-# calendar predictions for the year 2025, so I corrected those dates by hand.
+# I used the following code in GNU Emacs 26.1 to generate the "Rule Iran"
+# lines from 2008 through 2087. Emacs 26.1 uses Ed Reingold's
+# cal-persia implementation of Birashk's approximation, which in the
+# 2008-2087 range disagrees with the the astronomical Persian calendar
+# for Persian years 1404 (Gregorian 2025) and 1437 (Gregorian 2058),
+# so the following code special-case those years. See Table 15.1, page 264, of:
+# Edward M. Reingold and Nachum Dershowitz, Calendrical Calculations:
+# The Ultimate Edition, Cambridge University Press (2018).
+# https://www.cambridge.org/fr/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition
+# Page 258, footnote 2, of this book says there is some dispute over what will
+# happen in 2091 (and some other years after that), so this code
+# stops in 2087, as 2088 and 2089 agree with the "max" rule below.
+# (cl-loop
+# initially (require 'cal-persia)
+# with first-persian-year = 1387
+# with last-persian-year = 1466
+# ;; Exceptional years in the above range,
+# ;; from Reingold & Dershowitz Table 15.1, page 264:
+# with exceptional-persian-years = '(1404 1437)
+# with range-start = nil
+# for persian-year from first-persian-year to last-persian-year
+# do
+# (let*
+# ((exceptional-year-offset
+# (if (member persian-year exceptional-persian-years) 1 0))
+# (beg-dst-absolute
+# (+ (calendar-persian-to-absolute (list 1 1 persian-year))
+# exceptional-year-offset))
+# (end-dst-absolute
+# (+ (calendar-persian-to-absolute (list 6 30 persian-year))
+# exceptional-year-offset))
+# (next-year-beg-dst-absolute
+# (+ (calendar-persian-to-absolute (list 1 1 (1+ persian-year)))
+# (if (member (1+ persian-year) exceptional-persian-years) 1 0)))
+# (beg-dst (calendar-gregorian-from-absolute beg-dst-absolute))
+# (end-dst (calendar-gregorian-from-absolute end-dst-absolute))
+# (next-year-beg-dst (calendar-gregorian-from-absolute
+# next-year-beg-dst-absolute))
+# (year (calendar-extract-year beg-dst))
+# (range-end (if range-start year "only")))
+# (setq range-start (or range-start year))
+# (when (or (/= (calendar-extract-day beg-dst)
+# (calendar-extract-day next-year-beg-dst))
+# (= persian-year last-persian-year))
+# (insert
+# (format
+# "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t1:00\t-\n"
+# range-start range-end
+# (calendar-month-name (calendar-extract-month beg-dst) t)
+# (calendar-extract-day beg-dst)))
+# (insert
+# (format
+# "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t0\t-\n"
+# range-start range-end
+# (calendar-month-name (calendar-extract-month end-dst) t)
+# (calendar-extract-day end-dst)))
+# (setq range-start nil))))
#
# From Oscar van Vlijmen (2005-03-30), writing about future
# discrepancies between cal-persia and the Iranian calendar:
@@ -1290,61 +1425,113 @@
# thirtieth day of Shahrivar.
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Iran 1978 1980 - Mar 21 0:00 1:00 -
-Rule Iran 1978 only - Oct 21 0:00 0 -
-Rule Iran 1979 only - Sep 19 0:00 0 -
-Rule Iran 1980 only - Sep 23 0:00 0 -
-Rule Iran 1991 only - May 3 0:00 1:00 -
-Rule Iran 1992 1995 - Mar 22 0:00 1:00 -
-Rule Iran 1991 1995 - Sep 22 0:00 0 -
-Rule Iran 1996 only - Mar 21 0:00 1:00 -
-Rule Iran 1996 only - Sep 21 0:00 0 -
-Rule Iran 1997 1999 - Mar 22 0:00 1:00 -
-Rule Iran 1997 1999 - Sep 22 0:00 0 -
-Rule Iran 2000 only - Mar 21 0:00 1:00 -
-Rule Iran 2000 only - Sep 21 0:00 0 -
-Rule Iran 2001 2003 - Mar 22 0:00 1:00 -
-Rule Iran 2001 2003 - Sep 22 0:00 0 -
-Rule Iran 2004 only - Mar 21 0:00 1:00 -
-Rule Iran 2004 only - Sep 21 0:00 0 -
-Rule Iran 2005 only - Mar 22 0:00 1:00 -
-Rule Iran 2005 only - Sep 22 0:00 0 -
-Rule Iran 2008 only - Mar 21 0:00 1:00 -
-Rule Iran 2008 only - Sep 21 0:00 0 -
-Rule Iran 2009 2011 - Mar 22 0:00 1:00 -
-Rule Iran 2009 2011 - Sep 22 0:00 0 -
-Rule Iran 2012 only - Mar 21 0:00 1:00 -
-Rule Iran 2012 only - Sep 21 0:00 0 -
-Rule Iran 2013 2015 - Mar 22 0:00 1:00 -
-Rule Iran 2013 2015 - Sep 22 0:00 0 -
-Rule Iran 2016 only - Mar 21 0:00 1:00 -
-Rule Iran 2016 only - Sep 21 0:00 0 -
-Rule Iran 2017 2019 - Mar 22 0:00 1:00 -
-Rule Iran 2017 2019 - Sep 22 0:00 0 -
-Rule Iran 2020 only - Mar 21 0:00 1:00 -
-Rule Iran 2020 only - Sep 21 0:00 0 -
-Rule Iran 2021 2023 - Mar 22 0:00 1:00 -
-Rule Iran 2021 2023 - Sep 22 0:00 0 -
-Rule Iran 2024 only - Mar 21 0:00 1:00 -
-Rule Iran 2024 only - Sep 21 0:00 0 -
-Rule Iran 2025 2027 - Mar 22 0:00 1:00 -
-Rule Iran 2025 2027 - Sep 22 0:00 0 -
-Rule Iran 2028 2029 - Mar 21 0:00 1:00 -
-Rule Iran 2028 2029 - Sep 21 0:00 0 -
-Rule Iran 2030 2031 - Mar 22 0:00 1:00 -
-Rule Iran 2030 2031 - Sep 22 0:00 0 -
-Rule Iran 2032 2033 - Mar 21 0:00 1:00 -
-Rule Iran 2032 2033 - Sep 21 0:00 0 -
-Rule Iran 2034 2035 - Mar 22 0:00 1:00 -
-Rule Iran 2034 2035 - Sep 22 0:00 0 -
+Rule Iran 1978 1980 - Mar 20 24:00 1:00 -
+Rule Iran 1978 only - Oct 20 24:00 0 -
+Rule Iran 1979 only - Sep 18 24:00 0 -
+Rule Iran 1980 only - Sep 22 24:00 0 -
+Rule Iran 1991 only - May 2 24:00 1:00 -
+Rule Iran 1992 1995 - Mar 21 24:00 1:00 -
+Rule Iran 1991 1995 - Sep 21 24:00 0 -
+Rule Iran 1996 only - Mar 20 24:00 1:00 -
+Rule Iran 1996 only - Sep 20 24:00 0 -
+Rule Iran 1997 1999 - Mar 21 24:00 1:00 -
+Rule Iran 1997 1999 - Sep 21 24:00 0 -
+Rule Iran 2000 only - Mar 20 24:00 1:00 -
+Rule Iran 2000 only - Sep 20 24:00 0 -
+Rule Iran 2001 2003 - Mar 21 24:00 1:00 -
+Rule Iran 2001 2003 - Sep 21 24:00 0 -
+Rule Iran 2004 only - Mar 20 24:00 1:00 -
+Rule Iran 2004 only - Sep 20 24:00 0 -
+Rule Iran 2005 only - Mar 21 24:00 1:00 -
+Rule Iran 2005 only - Sep 21 24:00 0 -
+Rule Iran 2008 only - Mar 20 24:00 1:00 -
+Rule Iran 2008 only - Sep 20 24:00 0 -
+Rule Iran 2009 2011 - Mar 21 24:00 1:00 -
+Rule Iran 2009 2011 - Sep 21 24:00 0 -
+Rule Iran 2012 only - Mar 20 24:00 1:00 -
+Rule Iran 2012 only - Sep 20 24:00 0 -
+Rule Iran 2013 2015 - Mar 21 24:00 1:00 -
+Rule Iran 2013 2015 - Sep 21 24:00 0 -
+Rule Iran 2016 only - Mar 20 24:00 1:00 -
+Rule Iran 2016 only - Sep 20 24:00 0 -
+Rule Iran 2017 2019 - Mar 21 24:00 1:00 -
+Rule Iran 2017 2019 - Sep 21 24:00 0 -
+Rule Iran 2020 only - Mar 20 24:00 1:00 -
+Rule Iran 2020 only - Sep 20 24:00 0 -
+Rule Iran 2021 2023 - Mar 21 24:00 1:00 -
+Rule Iran 2021 2023 - Sep 21 24:00 0 -
+Rule Iran 2024 only - Mar 20 24:00 1:00 -
+Rule Iran 2024 only - Sep 20 24:00 0 -
+Rule Iran 2025 2027 - Mar 21 24:00 1:00 -
+Rule Iran 2025 2027 - Sep 21 24:00 0 -
+Rule Iran 2028 2029 - Mar 20 24:00 1:00 -
+Rule Iran 2028 2029 - Sep 20 24:00 0 -
+Rule Iran 2030 2031 - Mar 21 24:00 1:00 -
+Rule Iran 2030 2031 - Sep 21 24:00 0 -
+Rule Iran 2032 2033 - Mar 20 24:00 1:00 -
+Rule Iran 2032 2033 - Sep 20 24:00 0 -
+Rule Iran 2034 2035 - Mar 21 24:00 1:00 -
+Rule Iran 2034 2035 - Sep 21 24:00 0 -
+Rule Iran 2036 2037 - Mar 20 24:00 1:00 -
+Rule Iran 2036 2037 - Sep 20 24:00 0 -
+Rule Iran 2038 2039 - Mar 21 24:00 1:00 -
+Rule Iran 2038 2039 - Sep 21 24:00 0 -
+Rule Iran 2040 2041 - Mar 20 24:00 1:00 -
+Rule Iran 2040 2041 - Sep 20 24:00 0 -
+Rule Iran 2042 2043 - Mar 21 24:00 1:00 -
+Rule Iran 2042 2043 - Sep 21 24:00 0 -
+Rule Iran 2044 2045 - Mar 20 24:00 1:00 -
+Rule Iran 2044 2045 - Sep 20 24:00 0 -
+Rule Iran 2046 2047 - Mar 21 24:00 1:00 -
+Rule Iran 2046 2047 - Sep 21 24:00 0 -
+Rule Iran 2048 2049 - Mar 20 24:00 1:00 -
+Rule Iran 2048 2049 - Sep 20 24:00 0 -
+Rule Iran 2050 2051 - Mar 21 24:00 1:00 -
+Rule Iran 2050 2051 - Sep 21 24:00 0 -
+Rule Iran 2052 2053 - Mar 20 24:00 1:00 -
+Rule Iran 2052 2053 - Sep 20 24:00 0 -
+Rule Iran 2054 2055 - Mar 21 24:00 1:00 -
+Rule Iran 2054 2055 - Sep 21 24:00 0 -
+Rule Iran 2056 2057 - Mar 20 24:00 1:00 -
+Rule Iran 2056 2057 - Sep 20 24:00 0 -
+Rule Iran 2058 2059 - Mar 21 24:00 1:00 -
+Rule Iran 2058 2059 - Sep 21 24:00 0 -
+Rule Iran 2060 2062 - Mar 20 24:00 1:00 -
+Rule Iran 2060 2062 - Sep 20 24:00 0 -
+Rule Iran 2063 only - Mar 21 24:00 1:00 -
+Rule Iran 2063 only - Sep 21 24:00 0 -
+Rule Iran 2064 2066 - Mar 20 24:00 1:00 -
+Rule Iran 2064 2066 - Sep 20 24:00 0 -
+Rule Iran 2067 only - Mar 21 24:00 1:00 -
+Rule Iran 2067 only - Sep 21 24:00 0 -
+Rule Iran 2068 2070 - Mar 20 24:00 1:00 -
+Rule Iran 2068 2070 - Sep 20 24:00 0 -
+Rule Iran 2071 only - Mar 21 24:00 1:00 -
+Rule Iran 2071 only - Sep 21 24:00 0 -
+Rule Iran 2072 2074 - Mar 20 24:00 1:00 -
+Rule Iran 2072 2074 - Sep 20 24:00 0 -
+Rule Iran 2075 only - Mar 21 24:00 1:00 -
+Rule Iran 2075 only - Sep 21 24:00 0 -
+Rule Iran 2076 2078 - Mar 20 24:00 1:00 -
+Rule Iran 2076 2078 - Sep 20 24:00 0 -
+Rule Iran 2079 only - Mar 21 24:00 1:00 -
+Rule Iran 2079 only - Sep 21 24:00 0 -
+Rule Iran 2080 2082 - Mar 20 24:00 1:00 -
+Rule Iran 2080 2082 - Sep 20 24:00 0 -
+Rule Iran 2083 only - Mar 21 24:00 1:00 -
+Rule Iran 2083 only - Sep 21 24:00 0 -
+Rule Iran 2084 2086 - Mar 20 24:00 1:00 -
+Rule Iran 2084 2086 - Sep 20 24:00 0 -
+Rule Iran 2087 only - Mar 21 24:00 1:00 -
+Rule Iran 2087 only - Sep 21 24:00 0 -
#
-# The following rules are approximations starting in the year 2038.
-# These are the best post-2037 approximations available, given the
-# restrictions of a single rule using a Gregorian-based data format.
+# The following rules are approximations starting in the year 2088.
+# These are the best post-2088 approximations available, given the
+# restrictions of a single rule using ordinary Gregorian dates.
# At some point this table will need to be extended, though quite
# possibly Iran will change the rules first.
-Rule Iran 2036 max - Mar 21 0:00 1:00 -
-Rule Iran 2036 max - Sep 21 0:00 0 -
+Rule Iran 2088 max - Mar 20 24:00 1:00 -
+Rule Iran 2088 max - Sep 20 24:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Tehran 3:25:44 - LMT 1916
@@ -1456,6 +1643,24 @@
Rule Zion 1974 only - Oct 13 0:00 0 S
Rule Zion 1975 only - Apr 20 0:00 1:00 D
Rule Zion 1975 only - Aug 31 0:00 0 S
+
+# From Alois Treindl (2019-03-06):
+# http://www.moin.gov.il/Documents/שעון קיץ/clock-50-years-7-2014.pdf
+# From Isaac Starkman (2019-03-06):
+# Summer time was in that period in 1980 and 1984, see
+# https://www.ynet.co.il/articles/0,7340,L-3951073,00.html
+# You can of course read it in translation.
+# I checked the local newspapers for that years.
+# It started on midnight and end at 01.00 am.
+# From Paul Eggert (2019-03-06):
+# Also see this thread about the moin.gov.il URL:
+# https://mm.icann.org/pipermail/tz/2018-November/027194.html
+Rule Zion 1980 only - Aug 2 0:00 1:00 D
+Rule Zion 1980 only - Sep 13 1:00 0 S
+Rule Zion 1984 only - May 5 0:00 1:00 D
+Rule Zion 1984 only - Aug 25 1:00 0 S
+
+# From Shanks & Pottenger:
Rule Zion 1985 only - Apr 14 0:00 1:00 D
Rule Zion 1985 only - Sep 15 0:00 0 S
Rule Zion 1986 only - May 18 0:00 1:00 D
@@ -1714,7 +1919,9 @@
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
9:00 Japan J%sT
-# Since 1938, all Japanese possessions have been like Asia/Tokyo.
+# Since 1938, all Japanese possessions have been like Asia/Tokyo,
+# except that Truk (Chuuk), Ponape (Pohnpei), and Jaluit (Kosrae) did not
+# switch from +10 to +09 until 1941-04-01; see the 'australasia' file.
# Jordan
#
@@ -2004,8 +2211,10 @@
# and in Byalokoz) lists Ural river (plus 10 versts on its left bank) in
# the third time belt (before 1930 this means +03).
-# From Paul Eggert (2016-12-06):
-# The tables below reflect Golosunov's remarks, with exceptions as noted.
+# From Alexander Konzurovski (2018-12-20):
+# Qyzyolrda Region (Asia/Qyzylorda) is changing its time zone from
+# UTC+6 to UTC+5 effective December 21st, 2018. The legal document is
+# located here: http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
#
@@ -2019,8 +2228,6 @@
6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s
6:00 - +06
# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
-# This currently includes Qostanay (aka Kostanay, Kustanay) (KZ-KUS);
-# see comments below.
Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
5:00 - +05 1981 Apr 1
@@ -2031,21 +2238,22 @@
5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s
6:00 RussiaAsia +06/+07 1992 Mar 29 2:00s
5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
+ 6:00 - +06 2018 Dec 21 0:00
+ 5:00 - +05
+#
+# Qostanay (aka Kostanay, Kustanay) (KZ-KUS)
+# The 1991/2 rules are unclear partly because of the 1997 Turgai
+# reorganization.
+Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2
+ 4:00 - +04 1930 Jun 21
+ 5:00 - +05 1981 Apr 1
+ 5:00 1:00 +06 1981 Oct 1
+ 6:00 - +06 1982 Apr 1
+ 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s
+ 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s
+ 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
6:00 - +06
-# The following zone is like Asia/Qyzylorda except for being one
-# hour earlier from 1991-09-29 to 1992-03-29. The 1991/2 rules for
-# Qostanay are unclear partly because of the 1997 Turgai
-# reorganization, so this zone is commented out for now.
-#Zone Asia/Qostanay 4:14:20 - LMT 1924 May 2
-# 4:00 - +04 1930 Jun 21
-# 5:00 - +05 1981 Apr 1
-# 5:00 1:00 +06 1981 Oct 1
-# 6:00 - +06 1982 Apr 1
-# 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s
-# 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s
-# 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
-# 6:00 - +06
-#
+
# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
@@ -2139,21 +2347,43 @@
# started at June 1 in that year. For another example, the article in
# 1988 said that DST started at 2:00 AM in that year.
+# From Phake Nick (2018-10-27):
+# 1. According to official announcement from Korean government, the DST end
+# date in South Korea should be
+# 1955-09-08 without specifying time
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027977557
+# 1956-09-29 without specifying time
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027978341
+# 1957-09-21 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027979690#3
+# 1958-09-20 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027981189
+# 1959-09-19 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027982974#2
+# 1960-09-17 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0028044104
+# ...
+# 2.... https://namu.wiki/w/대한민국%20표준시 ... [says]
+# when Korea was using GMT+8:30 as standard time, the international
+# aviation/marine/meteorological industry in the country refused to
+# follow and continued to use GMT+9:00 for interoperability.
+
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule ROK 1948 only - Jun 1 0:00 1:00 D
-Rule ROK 1948 only - Sep 13 0:00 0 S
-Rule ROK 1949 only - Apr 3 0:00 1:00 D
-Rule ROK 1949 1951 - Sep Sun>=8 0:00 0 S
-Rule ROK 1950 only - Apr 1 0:00 1:00 D
-Rule ROK 1951 only - May 6 0:00 1:00 D
-Rule ROK 1955 only - May 5 0:00 1:00 D
-Rule ROK 1955 only - Sep 9 0:00 0 S
-Rule ROK 1956 only - May 20 0:00 1:00 D
-Rule ROK 1956 only - Sep 30 0:00 0 S
-Rule ROK 1957 1960 - May Sun>=1 0:00 1:00 D
-Rule ROK 1957 1960 - Sep Sun>=18 0:00 0 S
-Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D
-Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
+Rule ROK 1948 only - Jun 1 0:00 1:00 D
+Rule ROK 1948 only - Sep 12 24:00 0 S
+Rule ROK 1949 only - Apr 3 0:00 1:00 D
+Rule ROK 1949 1951 - Sep Sat>=7 24:00 0 S
+Rule ROK 1950 only - Apr 1 0:00 1:00 D
+Rule ROK 1951 only - May 6 0:00 1:00 D
+Rule ROK 1955 only - May 5 0:00 1:00 D
+Rule ROK 1955 only - Sep 8 24:00 0 S
+Rule ROK 1956 only - May 20 0:00 1:00 D
+Rule ROK 1956 only - Sep 29 24:00 0 S
+Rule ROK 1957 1960 - May Sun>=1 0:00 1:00 D
+Rule ROK 1957 1960 - Sep Sat>=17 24:00 0 S
+Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D
+Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
# From Paul Eggert (2016-08-23):
# The Korean Wikipedia entry gives the following sources for UT offsets:
@@ -2882,9 +3112,15 @@
# the official website, though the decree did not specify the exact
# time of the time shift.
# http://www.palestinecabinet.gov.ps/Website/AR/NDecrees/ViewFile.ashx?ID=e7a42ab7-ee23-435a-b9c8-a4f7e81f3817
+
+# From Even Scharning (2019-03-23):
+# DST in Palestine will start on 30 March this year, not 23 March as the time
+# zone database predicted.
+# https://ramallah.news/post/123610
#
-# From Paul Eggert (2018-03-16):
-# For 2016 on, predict spring transitions on March's fourth Saturday at 01:00.
+# From Tim Parenti (2019-03-23):
+# Combining this with the rules observed since 2016, adjust our spring
+# transition guess to Mar Sat>=24.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2915,7 +3151,7 @@
Rule Palestine 2013 only - Sep Fri>=21 0:00 0 -
Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 -
Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S
-Rule Palestine 2016 max - Mar Sat>=22 1:00 1:00 S
+Rule Palestine 2016 max - Mar Sat>=24 1:00 1:00 S
Rule Palestine 2016 max - Oct lastSat 1:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -2943,6 +3179,11 @@
# no information
# Philippines
+
+# From Paul Eggert (2018-11-18):
+# The Spanish initially used American (west-of-Greenwich) time.
+# It is unknown what time Manila kept when the British occupied it from
+# 1762-10-06 through 1764-04; for now assume it kept American time.
# On 1844-08-16, Narciso Clavería, governor-general of the
# Philippines, issued a proclamation announcing that 1844-12-30 was to
# be immediately followed by 1845-01-01; see R.H. van Gent's
@@ -3028,8 +3269,8 @@
# going to run on Higgins Time.' And so, until last year, it did." See:
# Antar E. Dinner at When? Saudi Aramco World, 1969 March/April. 2-3.
# http://archive.aramcoworld.com/issue/196902/dinner.at.when.htm
-# newspapers.com says a similar story about Higgins was published in the Port
-# Angeles (WA) Evening News, 1965-03-10, page 5, but I lack access to the text.
+# Also see: Antar EN. Arabian flying is confusing.
+# Port Angeles (WA) Evening News. 1965-03-10. page 3.
#
# The TZ database cannot represent quasi-solar time; airline time is the best
# we can do. The 1946 foreign air news digest of the U.S. Civil Aeronautics
@@ -3402,5 +3643,17 @@
8:00 - +08 1975 Jun 13
7:00 - +07
+# From Paul Eggert (2019-02-19):
+#
+# The Ho Chi Minh entry suffices for most purposes as it agrees with all of
+# Vietnam since 1975-06-13. Presumably clocks often changed in south Vietnam
+# in the early 1970s as locations changed hands during the war; however the
+# details are unknown and would likely be too voluminous for this database.
+#
+# For timestamps in north Vietnam back to 1970 (the tzdb cutoff),
+# use Asia/Bangkok; see the VN entries in the file zone1970.tab.
+# For timestamps before 1970, see Asia/Hanoi in the file 'backzone'.
+
+
# Yemen
# See Asia/Riyadh.
--- a/make/data/tzdata/australasia Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/australasia Mon Jul 22 11:08:27 2019 +0530
@@ -425,10 +425,44 @@
# it is uninhabited.
# Guam
+
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# http://guamlegislature.com/Public_Laws_5th/PL05-025.pdf
+# http://documents.guam.gov/wp-content/uploads/E.O.-59-7-Guam-Daylight-Savings-Time-May-6-1959.pdf
+Rule Guam 1959 only - Jun 27 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-61-5-Revocation-of-Daylight-Saving-Time-and-Restoratio.pdf
+Rule Guam 1961 only - Jan 29 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-67-13-Guam-Daylight-Savings-Time.pdf
+Rule Guam 1967 only - Sep 1 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-69-2-Repeal-of-Guam-Daylight-Saving-Time.pdf
+Rule Guam 1969 only - Jan 26 0:01 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-69-10-Guam-Daylight-Saving-Time.pdf
+Rule Guam 1969 only - Jun 22 2:00 1:00 D
+Rule Guam 1969 only - Aug 31 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-70-10-Guam-Daylight-Saving-Time.pdf
+# http://documents.guam.gov/wp-content/uploads/E.O.-70-30-End-of-Guam-Daylight-Saving-Time.pdf
+# http://documents.guam.gov/wp-content/uploads/E.O.-71-5-Guam-Daylight-Savings-Time.pdf
+Rule Guam 1970 1971 - Apr lastSun 2:00 1:00 D
+Rule Guam 1970 1971 - Sep Sun>=1 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-73-28.-Guam-Day-light-Saving-Time.pdf
+Rule Guam 1973 only - Dec 16 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-74-7-Guam-Daylight-Savings-Time-Rescinded.pdf
+Rule Guam 1974 only - Feb 24 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-76-13-Daylight-Savings-Time.pdf
+Rule Guam 1976 only - May 26 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-76-25-Revocation-of-E.O.-76-13.pdf
+Rule Guam 1976 only - Aug 22 2:01 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-77-4-Daylight-Savings-Time.pdf
+Rule Guam 1977 only - Apr 24 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-77-18-Guam-Standard-Time.pdf
+Rule Guam 1977 only - Aug 28 2:00 0 S
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Guam -14:21:00 - LMT 1844 Dec 31
9:39:00 - LMT 1901 # Agana
- 10:00 - GST 2000 Dec 23 # Guam
+ 10:00 - GST 1941 Dec 10 # Guam
+ 9:00 - +09 1944 Jul 31
+ 10:00 Guam G%sT 2000 Dec 23
10:00 - ChST # Chamorro Standard Time
Link Pacific/Guam Pacific/Saipan # N Mariana Is
@@ -450,31 +484,56 @@
# Marshall Is
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Majuro 11:24:48 - LMT 1901
- 11:00 - +11 1969 Oct
- 12:00 - +12
-Zone Pacific/Kwajalein 11:09:20 - LMT 1901
- 11:00 - +11 1969 Oct
- -12:00 - -12 1993 Aug 20
- 12:00 - +12
+Zone Pacific/Majuro 11:24:48 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1944 Jan 30
+ 11:00 - +11 1969 Oct
+ 12:00 - +12
+Zone Pacific/Kwajalein 11:09:20 - LMT 1901
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1944 Feb 6
+ 11:00 - +11 1969 Oct
+ -12:00 - -12 1993 Aug 20 24:00
+ 12:00 - +12
# Micronesia
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Chuuk 10:07:08 - LMT 1901
- 10:00 - +10
-Zone Pacific/Pohnpei 10:32:52 - LMT 1901 # Kolonia
- 11:00 - +11
-Zone Pacific/Kosrae 10:51:56 - LMT 1901
- 11:00 - +11 1969 Oct
- 12:00 - +12 1999
- 11:00 - +11
+Zone Pacific/Chuuk -13:52:52 - LMT 1844 Dec 31
+ 10:07:08 - LMT 1901
+ 10:00 - +10 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 10:00 - +10
+Zone Pacific/Pohnpei -13:27:08 - LMT 1844 Dec 31 # Kolonia
+ 10:32:52 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 11:00 - +11
+Zone Pacific/Kosrae -13:08:04 - LMT 1844 Dec 31
+ 10:51:56 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 11:00 - +11 1969 Oct
+ 12:00 - +12 1999
+ 11:00 - +11
# Nauru
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Nauru 11:07:40 - LMT 1921 Jan 15 # Uaobe
- 11:30 - +1130 1942 Mar 15
- 9:00 - +09 1944 Aug 15
- 11:30 - +1130 1979 May
+ 11:30 - +1130 1942 Aug 29
+ 9:00 - +09 1945 Sep 8
+ 11:30 - +1130 1979 Feb 10 2:00
12:00 - +12
# New Caledonia
@@ -575,8 +634,9 @@
# Palau (Belau)
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Palau 8:57:56 - LMT 1901 # Koror
- 9:00 - +09
+Zone Pacific/Palau -15:02:04 - LMT 1844 Dec 31 # Koror
+ 8:57:56 - LMT 1901
+ 9:00 - +09
# Papua New Guinea
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -838,7 +898,7 @@
# tz@iana.org for general use in the future). For more, please see
# the file CONTRIBUTING in the tz distribution.
-# From Paul Eggert (2017-02-10):
+# From Paul Eggert (2018-11-18):
#
# Unless otherwise specified, the source for data through 1990 is:
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -863,6 +923,7 @@
# A reliable and entertaining source about time zones is
# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
#
+# I invented the abbreviation marked "*".
# The following abbreviations are from other sources.
# Corrections are welcome!
# std dst
@@ -870,7 +931,7 @@
# 8:00 AWST AWDT Western Australia
# 9:30 ACST ACDT Central Australia
# 10:00 AEST AEDT Eastern Australia
-# 10:00 GST Guam through 2000
+# 10:00 GST GDT* Guam through 2000
# 10:00 ChST Chamorro
# 11:30 NZMT NZST New Zealand through 1945
# 12:00 NZST NZDT New Zealand 1946-present
@@ -1569,28 +1630,70 @@
# Kwajalein
-# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
-# I wonder what happened in Kwajalein, where there was NO Friday,
-# 1993-08-20. Thursday night at midnight Kwajalein switched sides with
-# respect to the International Date Line, to rejoin its fellow islands,
-# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
+# From an AP article (1993-08-22):
+# "The nearly 3,000 Americans living on this remote Pacific atoll have a good
+# excuse for not remembering Saturday night: there wasn't one. Residents were
+# going to bed Friday night and waking up Sunday morning because at midnight
+# -- 8 A.M. Eastern daylight time on Saturday -- Kwajalein was jumping from
+# one side of the international date line to the other."
+# "In Marshall Islands, Friday is followed by Sunday", NY Times. 1993-08-22.
+# https://www.nytimes.com/1993/08/22/world/in-marshall-islands-friday-is-followed-by-sunday.html
+
+# From Phake Nick (2018-10-27):
+# <https://wiki.suikawiki.org/n/南洋群島の標準時> ... pointed out that
+# currently tzdata say Pacific/Kwajalein switched from GMT+11 to GMT-12 in
+# 1969 October without explanation, however an 1993 article from NYT say it
+# synchorized its day with US mainland about 40 years ago and thus the switch
+# should occur at around 1950s instead.
+#
+# From Paul Eggert (2018-11-18):
+# The NYT (actually, AP) article is vague and possibly wrong about this.
+# The article says the earlier switch was "40 years ago when the United States
+# Army established a missile test range here". However, the Kwajalein Test
+# Center was established on 1960-10-01 and was run by the US Navy. It was
+# transferred to the US Army on 1964-07-01. See "Seize the High Ground"
+# <https://history.army.mil/html/books/070/70-88-1/cmhPub_70-88-1.pdf>.
+# Given that Shanks was right on the money about the 1993 change, I'm inclined
+# to take Shanks's word for the 1969 change unless we find better evidence.
# N Mariana Is, Guam
+# From Phake Nick (2018-10-27):
+# Guam Island was briefly annexed by Japan during ... year 1941-1944 ...
+# however there are no detailed information about what time it use during that
+# period. It would probably be reasonable to assume Guam use GMT+9 during
+# that period of time like the surrounding area.
+
+# From Paul Eggert (2018-11-18):
# Howse writes (p 153) "The Spaniards, on the other hand, reached the
# Philippines and the Ladrones from America," and implies that the Ladrones
# (now called the Marianas) kept American date for quite some time.
# For now, we assume the Ladrones switched at the same time as the Philippines;
# see Asia/Manila.
-
+#
+# Use 1941-12-10 and 1944-07-31 for Guam WWII transitions, as the rough start
+# and end of Japanese control of Agana. We don't know whether the Northern
+# Marianas followed Guam's DST rules from 1959 through 1977; for now, assume
+# they did as that avoids the need for a separate zone due to our 1970 cutoff.
+#
# US Public Law 106-564 (2000-12-23) made UT +10 the official standard time,
# under the name "Chamorro Standard Time". There is no official abbreviation,
# but Congressman Robert A. Underwood, author of the bill that became law,
# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
+# See also the commentary for Micronesia.
-# Micronesia
+
+# Marshall Is
+# See the commentary for Micronesia.
+
+
+# Micronesia (and nearby)
+
+# From Paul Eggert (2018-11-18):
+# Like the Ladrones (see Guam commentary), assume the Spanish East Indies
+# kept American time until the Philippines switched at the end of 1844.
# Alan Eugene Davis writes (1996-03-16),
# "I am certain, having lived there for the past decade, that 'Truk'
@@ -1606,6 +1709,95 @@
# that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
# We don't know when Kosrae switched from +12; assume January 1 for now.
+# From Phake Nick (2018-10-27):
+#
+# From a Japanese wiki site https://wiki.suikawiki.org/n/南洋群島の標準時
+# ...
+# For "Southern Islands" (modern region of Mariana + Palau + Federation of
+# Micronesia + Marshall Islands):
+#
+# A 1906 Japanese magazine shown the Caroline Islands and Mariana Islands
+# who was occupied by Germany at the time as GMT+10, together with the like
+# of German New Guinea. However there is a marking saying it have not been
+# implemented (yet). No further information after that were found.
+#
+# Japan invaded those islands in 1914, and records shows that they were
+# instructed to use JST at the time.
+#
+# 1915 January telecommunication record on the Jaluit Atoll shows they use
+# the meridian of 170E as standard time (GMT+11:20), which is similar to the
+# longitude of the atoll.
+# 1915 February record say the 170E standard time is to be used until
+# February 9 noon, and after February 9 noon they are to use JST.
+# However these are time used within the Japanese Military at the time and
+# probably does not reflect the time used by local resident at the time (that
+# is if they keep their own time back then)
+#
+# In January 1919 the occupying force issued a command that split the area
+# into three different timezone with meridian of 135E, 150E, 165E (JST+0, +1,
+# +2), and the command was to become effective from February 1 of the same
+# year. Despite the target of the command is still only for the occupying
+# force itself, further publication have described the time as the standard
+# time for the occupied area and thus it can probably be seen as such.
+# * Area that use meridian of 135E: Palau and Yap civil administration area
+# (Southern Islands Western Standard Time)
+# * Area that use meridian of 150E: Truk (Chuuk) and Saipan civil
+# administration area (Southern Islands Central Standard Time)
+# * Area that use meridian of 165E: Ponape (Pohnpei) and Jaluit civil
+# administration area (Southern Islands Eastern Standard Time).
+# * In the next few years Japanese occupation of those islands have been
+# formalized via League of Nation Mandate (South Pacific Mandate) and formal
+# governance structure have been established, these district [become
+# subprefectures] and timezone classification have been inherited as standard
+# time of the area.
+# * Saipan subprefecture include Mariana islands (exclude Guam which was
+# occupied by America at the time), Palau and Yap subprefecture rule the
+# Western Caroline Islands with 137E longitude as border, Truk and Ponape
+# subprefecture rule the Eastern Caroline Islands with 154E as border, Ponape
+# subprefecture also rule part of Marshall Islands to the west of 164E
+# starting from (1918?) and Jaluit subprefecture rule the rest of the
+# Marshall Islands.
+#
+# And then in year 1937, an announcement was made to change the time in the
+# area into 2 timezones:
+# * Area that use meridian of 135E: area administered by Palau, Yap and
+# Saipan subprefecture (Southern Islands Western Standard Time)
+# * Area that use meridian of 150E: area administered by Truk (Chuuk),
+# Ponape (Pohnpei) and Jaluit subprefecture (Southern Islands Eastern
+# Standard Time)
+#
+# Another announcement issued in 1941 say that on April 1 that year,
+# standard time of the Southern Islands would be changed to use the meridian
+# of 135E (GMT+9), and thus abolishing timezone different within the area.
+#
+# Then Pacific theater of WWII started and Japan slowly lose control on the
+# island. The webpage I linked above contain no information during this
+# period of time....
+#
+# After the end of WWII, in 1946 February, a document written by the
+# (former?) Japanese military personnel describe there are 3 hours time
+# different between Caroline islands time/Wake island time and the Chungking
+# time, which would mean the time being used there at the time was GMT+10.
+#
+# After that, the area become Trust Territories of the Pacific Islands
+# under American administration from year 1947. The site listed some
+# American/International books/maps/publications about time used in those
+# area during this period of time but they doesn't seems to be reliable
+# information so it would be the best if someone know where can more reliable
+# information can be found.
+#
+#
+# From Paul Eggert (2018-11-18):
+#
+# For the above, use vague dates like "1914" and "1945" for transitions that
+# plausibly exist but for which the details are not known. The information
+# for Wake is too sketchy to act on.
+#
+# The 1906 GMT+10 info about German-controlled islands might not have been
+# done, so omit it from the data for now.
+#
+# The Jaluit info governs Kwajalein.
+
# Midway
@@ -1623,6 +1815,29 @@
# started DST on June 3. Possibly DST was observed other years
# in Midway, but we have no record of it.
+# Nauru
+
+# From Phake Nick (2018-10-31):
+# Currently, the tz database say Nauru use LMT until 1921, and then
+# switched to GMT+11:30 for the next two decades.
+# However, a number of timezone map published in America/Japan back then
+# showed its timezone as GMT+11 per https://wiki.suikawiki.org/n/ナウルの標準時
+# And it would also be nice if the 1921 transition date could be sourced.
+# ...
+# The "Nauru Standard Time Act 1978 Time Change"
+# http://ronlaw.gov.nr/nauru_lpms/files/gazettes/4b23a17d2030150404db7a5fa5872f52.pdf#page=3
+# based on "Nauru Standard Time Act 1978 Time Change"
+# http://www.paclii.org/nr/legis/num_act/nsta1978207/ defined that "Nauru
+# Alternative Time" (GMT+12) should be in effect from 1979 Feb.
+#
+# From Paul Eggert (2018-11-19):
+# The 1921-01-15 introduction of standard time is in Shanks; it is also in
+# "Standard Time Throughout the World", US National Bureau of Standards (1935),
+# page 3, which does not give the UT offset. In response to a comment by
+# Phake Nick I set the Nauru time of occupation by Japan to
+# 1942-08-29/1945-09-08 by using dates from:
+# https://en.wikipedia.org/wiki/Japanese_occupation_of_Nauru
+
# Norfolk
# From Alexander Krivenyshev (2015-09-23):
@@ -1638,6 +1853,9 @@
# other than in 1974/5. See:
# https://www.timeanddate.com/time/australia/norfolk-island.html
+# Palau
+# See commentary for Micronesia.
+
# Pitcairn
# From Rives McDow (1999-11-08):
@@ -1802,6 +2020,9 @@
# From Paul Eggert (2003-03-23):
# We have no other report of DST in Wake Island, so omit this info for now.
+# See also the commentary for Micronesia.
+
+
###############################################################################
# The International Date Line
--- a/make/data/tzdata/backward Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/backward Mon Jul 22 11:08:27 2019 +0530
@@ -100,6 +100,7 @@
Link America/Havana Cuba
Link Africa/Cairo Egypt
Link Europe/Dublin Eire
+Link Etc/UTC Etc/UCT
Link Europe/London Europe/Belfast
Link Europe/Chisinau Europe/Tiraspol
Link Europe/London GB
@@ -134,7 +135,7 @@
Link Asia/Seoul ROK
Link Asia/Singapore Singapore
Link Europe/Istanbul Turkey
-Link Etc/UCT UCT
+Link Etc/UTC UCT
Link America/Anchorage US/Alaska
Link America/Adak US/Aleutian
Link America/Phoenix US/Arizona
--- a/make/data/tzdata/etcetera Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/etcetera Mon Jul 22 11:08:27 2019 +0530
@@ -42,7 +42,6 @@
Zone Etc/GMT 0 - GMT
Zone Etc/UTC 0 - UTC
-Zone Etc/UCT 0 - UCT
# The following link uses older naming conventions,
# but it belongs here, not in the file 'backward',
--- a/make/data/tzdata/europe Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/europe Mon Jul 22 11:08:27 2019 +0530
@@ -1878,7 +1878,7 @@
1:00 Belgium CE%sT 1977
1:00 EU CE%sT
-# Macedonia
+# North Macedonia
# See Europe/Belgrade.
# Malta
@@ -3382,7 +3382,7 @@
Link Europe/Belgrade Europe/Ljubljana # Slovenia
Link Europe/Belgrade Europe/Podgorica # Montenegro
Link Europe/Belgrade Europe/Sarajevo # Bosnia and Herzegovina
-Link Europe/Belgrade Europe/Skopje # Macedonia
+Link Europe/Belgrade Europe/Skopje # North Macedonia
Link Europe/Belgrade Europe/Zagreb # Croatia
# Slovakia
--- a/make/data/tzdata/iso3166.tab Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/iso3166.tab Mon Jul 22 11:08:27 2019 +0530
@@ -32,8 +32,8 @@
# All text uses UTF-8 encoding. The columns of the table are as follows:
#
# 1. ISO 3166-1 alpha-2 country code, current as of
-# ISO 3166-1 N905 (2016-11-15). See: Updates on ISO 3166-1
-# http://isotc.iso.org/livelink/livelink/Open/16944257
+# ISO 3166-1 N976 (2018-11-06). See: Updates on ISO 3166-1
+# https://isotc.iso.org/livelink/livelink/Open/16944257
# 2. The usual English name for the coded region,
# chosen so that alphabetic sorting of subsets produces helpful lists.
# This is not the same as the English name in the ISO 3166 tables.
@@ -189,7 +189,7 @@
MF St Martin (French)
MG Madagascar
MH Marshall Islands
-MK Macedonia
+MK North Macedonia
ML Mali
MM Myanmar (Burma)
MN Mongolia
@@ -258,7 +258,7 @@
SV El Salvador
SX St Maarten (Dutch)
SY Syria
-SZ Swaziland
+SZ Eswatini (Swaziland)
TC Turks & Caicos Is
TD Chad
TF French Southern & Antarctic Lands
--- a/make/data/tzdata/leapseconds Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/leapseconds Mon Jul 22 11:08:27 2019 +0530
@@ -42,9 +42,12 @@
# See: Levine J. Coordinated Universal Time and the leap second.
# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995
# <https://ieeexplore.ieee.org/document/7909995>.
+
# There were no leap seconds before 1972, because the official mechanism
# accounting for the discrepancy between atomic time and the earth's rotation
-# did not exist.
+# did not exist. The first ("1 Jan 1972") data line in leap-seconds.list
+# does not denote a leap second; it denotes the start of the current definition
+# of UTC.
# The correction (+ or -) is made at the given time, so lines
# will typically look like:
@@ -83,7 +86,7 @@
# POSIX timestamps for the data in this file:
#updated 1467936000
-#expires 1561680000
+#expires 1577491200
-# Updated through IERS Bulletin C56
-# File expires on: 28 June 2019
+# Updated through IERS Bulletin C57
+# File expires on: 28 December 2019
--- a/make/data/tzdata/northamerica Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/northamerica Mon Jul 22 11:08:27 2019 +0530
@@ -622,6 +622,26 @@
# between AKST and AKDT from now on....
# https://www.krbd.org/2015/10/30/annette-island-times-they-are-a-changing/
+# From Ryan Stanley (2018-11-06):
+# The Metlakatla community in Alaska has decided not to change its
+# clock back an hour starting on November 4th, 2018 (day before yesterday).
+# They will be gmtoff=-28800 year-round.
+# https://www.facebook.com/141055983004923/photos/pb.141055983004923.-2207520000.1541465673./569081370202380/
+
+# From Paul Eggert (2018-12-16):
+# In a 2018-12-11 special election, Metlakatla voted to go back to
+# Alaska time (including daylight saving time) starting next year.
+# https://www.krbd.org/2018/12/12/metlakatla-to-follow-alaska-standard-time-allow-liquor-sales/
+#
+# From Ryan Stanley (2019-01-11):
+# The community will be changing back on the 20th of this month...
+# From Tim Parenti (2019-01-11):
+# Per an announcement on the Metlakatla community's official Facebook page, the
+# "fall back" will be on Sunday 2019-01-20 at 02:00:
+# https://www.facebook.com/141055983004923/photos/607150969728753/
+# So they won't be waiting for Alaska to join them on 2019-03-10, but will
+# rather change their clocks twice in seven weeks.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32
-8:57:41 - LMT 1900 Aug 20 12:00
@@ -648,6 +668,8 @@
-8:00 - PST 1969
-8:00 US P%sT 1983 Oct 30 2:00
-8:00 - PST 2015 Nov 1 2:00
+ -9:00 US AK%sT 2018 Nov 4 2:00
+ -8:00 - PST 2019 Jan 20 2:00
-9:00 US AK%sT
Zone America/Yakutat 14:41:05 - LMT 1867 Oct 19 15:12:18
-9:18:55 - LMT 1900 Aug 20 12:00
@@ -808,6 +830,22 @@
# For a map of Indiana's time zone regions, see:
# https://en.wikipedia.org/wiki/Time_in_Indiana
#
+# From Paul Eggert (2018-11-30):
+# A brief but entertaining history of time in Indiana describes a 1949 debate
+# in the Indiana House where city legislators (who favored "fast time")
+# tussled with farm legislators (who didn't) over a bill to outlaw DST:
+# "Lacking enough votes, the city faction tries to filibuster until time runs
+# out on the session at midnight, but rural champion Rep. Herbert Copeland,
+# R-Madison, leans over the gallery railing and forces the official clock
+# back to 9 p.m., breaking it in the process. The clock sticks on 9 as the
+# debate rages on into the night. The filibuster finally dies out and the
+# bill passes, while outside the chamber, clocks read 3:30 a.m. In the end,
+# it doesn't matter which side won. The law has no enforcement powers and
+# is simply ignored by fast-time communities."
+# How Indiana went from 'God's time' to split zones and daylight-saving.
+# Indianapolis Star. 2018-11-27 14:58 -05.
+# https://www.indystar.com/story/news/politics/2018/11/27/indianapolis-indiana-time-zone-history-central-eastern-daylight-savings-time/2126300002/
+#
# From Paul Eggert (2007-08-17):
# Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
# with the following exceptions:
--- a/make/data/tzdata/zone.tab Tue Jul 16 17:00:00 2019 -0700
+++ b/make/data/tzdata/zone.tab Mon Jul 22 11:08:27 2019 +0530
@@ -262,6 +262,7 @@
KY +1918-08123 America/Cayman
KZ +4315+07657 Asia/Almaty Kazakhstan (most areas)
KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda
+KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay
KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe
KZ +4431+05016 Asia/Aqtau Mangghystau/Mankistau
KZ +4707+05156 Asia/Atyrau Atyrau/Atirau/Gur'yev
@@ -355,9 +356,9 @@
RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad
RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area
RU +4457+03406 Europe/Simferopol MSK+00 - Crimea
-RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd
RU +5836+04939 Europe/Kirov MSK+00 - Kirov
RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan
+RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd
RU +5134+04602 Europe/Saratov MSK+01 - Saratov
RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk
RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia
--- a/make/hotspot/lib/CompileJvm.gmk Tue Jul 16 17:00:00 2019 -0700
+++ b/make/hotspot/lib/CompileJvm.gmk Mon Jul 22 11:08:27 2019 +0530
@@ -47,6 +47,8 @@
$(EXTRA_LDFLAGS) \
#
+JVM_ASFLAGS += $(EXTRA_ASFLAGS)
+
JVM_LIBS += \
$(JVM_LIBS_FEATURES) \
#
@@ -260,6 +262,15 @@
#
# Search the output for the operator(s) of interest, to see where they are
# referenced.
+#
+# When a reference to the global 'operator delete' is reported, it might be
+# due to a "deleting destructor". In this case, objdump may show the
+# reference to be associated with but not actually in a destructor. A
+# deleting destructor is automatically generated for a class whose destructor
+# is virtual. A deleting destructor requires an accessible 'operator delete'
+# for the associated class. If the class doesn't provide a more specific
+# declaration (either directly or by inheriting from a class that provides
+# one) then the global definition will be used, triggering this check.
ifneq ($(GENERATE_COMPILE_COMMANDS_ONLY), true)
ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang solstudio), )
--- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java Mon Jul 22 11:08:27 2019 +0530
@@ -108,7 +108,7 @@
private static final ResourceBundle.Control defCon =
ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
- private static final String[] AVAILABLE_TZIDS = TimeZone.getAvailableIDs();
+ private static Set<String> AVAILABLE_TZIDS;
private static String zoneNameTempFile;
private static String tzDataDir;
private static final Map<String, String> canonicalTZMap = new HashMap<>();
@@ -730,7 +730,7 @@
});
}
- Arrays.stream(AVAILABLE_TZIDS).forEach(tzid -> {
+ getAvailableZoneIds().stream().forEach(tzid -> {
// If the tzid is deprecated, get the data for the replacement id
String tzKey = Optional.ofNullable((String)handlerSupplMeta.get(tzid))
.orElse(tzid);
@@ -1074,8 +1074,20 @@
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
+ // This method assumes handlerMetaZones is already initialized
+ private static Set<String> getAvailableZoneIds() {
+ assert handlerMetaZones != null;
+ if (AVAILABLE_TZIDS == null) {
+ AVAILABLE_TZIDS = new HashSet<>(ZoneId.getAvailableZoneIds());
+ AVAILABLE_TZIDS.addAll(handlerMetaZones.keySet());
+ AVAILABLE_TZIDS.remove(MetaZonesParseHandler.NO_METAZONE_KEY);
+ }
+
+ return AVAILABLE_TZIDS;
+ }
+
private static Stream<String> zidMapEntry() {
- return ZoneId.getAvailableZoneIds().stream()
+ return getAvailableZoneIds().stream()
.map(id -> {
String canonId = canonicalTZMap.getOrDefault(id, id);
String meta = handlerMetaZones.get(canonId);
--- a/make/jdk/src/classes/build/tools/fixuppandoc/Main.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/fixuppandoc/Main.java Mon Jul 22 11:08:27 2019 +0530
@@ -81,6 +81,10 @@
*
* Update the content string, to indicate it has been processed by this program.
*
+ * <h2>{@code <nav id="TOC">}</h2>
+ *
+ * Set attribute {@code title="Table Of Contents"}
+ *
*/
public class Main {
/**
@@ -273,6 +277,11 @@
}
// <main> is not permitted within these elements
allowMain = false;
+ if (name.equals("nav") && Objects.equals(attrs.get("id"), "TOC")) {
+ out.write(buffer.toString()
+ .replaceAll(">$", " title=\"Table Of Contents\">"));
+ buffer.setLength(0);
+ }
break;
case "body":
--- a/make/jdk/src/classes/build/tools/jdwpgen/AbstractCommandNode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/jdwpgen/AbstractCommandNode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
class AbstractCommandNode extends AbstractNamedNode {
void document(PrintWriter writer) {
- writer.println("<h5 id=\"" + context.whereC + "\">" + name +
- " Command (" + nameNode.value() + ")</h5>");
+ writer.println("<h3 id=\"" + context.whereC + "\">" + name +
+ " Command (" + nameNode.value() + ")</h3>");
writer.println(comment());
writer.println("<dl>");
for (Node node : components) {
--- a/make/jdk/src/classes/build/tools/jdwpgen/AbstractNamedNode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/jdwpgen/AbstractNamedNode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,8 +62,8 @@
}
void document(PrintWriter writer) {
- writer.println("<h4 id=\"" + name + "\">" + name +
- " Command Set</h4>");
+ writer.println("<h2 id=\"" + name + "\">" + name +
+ " Command Set</h2>");
for (Node node : components) {
node.document(writer);
}
--- a/make/jdk/src/classes/build/tools/jdwpgen/CommandSetNode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/jdwpgen/CommandSetNode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,9 @@
}
void document(PrintWriter writer) {
- writer.println("<h4 id=\"" + context.whereC + "\">" + name +
+ writer.println("<h2 id=\"" + context.whereC + "\">" + name +
" Command Set (" +
- nameNode.value() + ")</h4>");
+ nameNode.value() + ")</h2>");
writer.println(comment());
for (Node node : components) {
node.document(writer);
--- a/make/jdk/src/classes/build/tools/jdwpgen/ConstantSetNode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/jdwpgen/ConstantSetNode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,8 +54,8 @@
}
void document(PrintWriter writer) {
- writer.println("<h4 id=\"" + context.whereC + "\">" + name +
- " Constants</h4>");
+ writer.println("<h2 id=\"" + context.whereC + "\">" + name +
+ " Constants</h2>");
writer.println(comment());
writer.println("<table><tr>");
writer.println("<th style=\"width: 20%\"><th style=\"width: 5%\"><th style=\"width: 65%\">");
--- a/make/jdk/src/classes/build/tools/jdwpgen/RootNode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/make/jdk/src/classes/build/tools/jdwpgen/RootNode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,11 +52,16 @@
writer.println("</style>");
writer.println("</head>");
writer.println("<body>");
- writer.println("<ul role=\"navigation\">");
+ writer.println("<div class=\"centered\" role=\"banner\">");
+ writer.println("<h1 id=\"Protocol Details\">Java Debug Wire Protocol Details</h1>");
+ writer.println("</div>");
+ writer.println("<nav>");
+ writer.println("<ul>");
for (Node node : components) {
node.documentIndex(writer);
}
writer.println("</ul>");
+ writer.println("</nav>");
writer.println("<div role=\"main\">");
for (Node node : components) {
node.document(writer);
--- a/make/launcher/LauncherCommon.gmk Tue Jul 16 17:00:00 2019 -0700
+++ b/make/launcher/LauncherCommon.gmk Mon Jul 22 11:08:27 2019 +0530
@@ -235,7 +235,10 @@
FORMAT := man, \
FILTER := $(PANDOC_TROFF_MANPAGE_FILTER), \
POST_PROCESS := $(MAN_POST_PROCESS), \
- REPLACEMENTS := @@VERSION_SHORT@@ => $(VERSION_SHORT), \
+ REPLACEMENTS := \
+ @@COPYRIGHT_YEAR@@ => $(COPYRIGHT_YEAR) ; \
+ @@VERSION_SHORT@@ => $(VERSION_SHORT) ; \
+ @@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION), \
EXTRA_DEPS := $(PANDOC_TROFF_MANPAGE_FILTER) \
$(PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT), \
))
--- a/make/test/JtregNativeHotspot.gmk Tue Jul 16 17:00:00 2019 -0700
+++ b/make/test/JtregNativeHotspot.gmk Mon Jul 22 11:08:27 2019 +0530
@@ -862,12 +862,13 @@
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libredefineClasses := -lpthread
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeinvoke := -ljvm -lpthread
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exestack-gap := -ljvm -lpthread
+ BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exestack-tls := -ljvm
BUILD_TEST_exeinvoke_exeinvoke.c_OPTIMIZATION := NONE
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeFPRegs := -ldl
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libAsyncGetCallTraceTest := -ldl
else
BUILD_HOTSPOT_JTREG_EXCLUDE += libtest-rw.c libtest-rwx.c libTestJNI.c \
- exeinvoke.c exestack-gap.c libAsyncGetCallTraceTest.cpp
+ exeinvoke.c exestack-gap.c exestack-tls.c libAsyncGetCallTraceTest.cpp
endif
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -99,7 +99,7 @@
__ xchg(access.resolved_addr(), value_opr, result, tmp);
if (access.is_oop()) {
- result = load_reference_barrier(access.gen(), result, access.access_emit_info(), true);
+ result = load_reference_barrier(access.gen(), result);
if (ShenandoahSATBBarrier) {
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr,
result /* pre_val */);
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/shenandoahForwarding.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahRuntime.hpp"
@@ -47,7 +47,7 @@
Register src, Register dst, Register count, RegSet saved_regs) {
if (is_oop) {
bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
- if (ShenandoahSATBBarrier && !dest_uninitialized && !ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc()) {
+ if (ShenandoahSATBBarrier && !dest_uninitialized) {
Label done;
@@ -282,6 +282,40 @@
__ leave();
}
+void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Register tmp) {
+ if (!ShenandoahLoadRefBarrier) {
+ return;
+ }
+
+ assert(dst != rscratch2, "need rscratch2");
+
+ Label is_null;
+ Label done;
+
+ __ cbz(dst, is_null);
+
+ __ enter();
+
+ Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
+ __ ldrb(rscratch2, gc_state);
+
+ // Check for heap in evacuation phase
+ __ tbz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, done);
+
+ __ mov(rscratch2, dst);
+ __ push_call_clobbered_registers();
+ __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native));
+ __ mov(r0, rscratch2);
+ __ blrt(lr, 1, 0, MacroAssembler::ret_type_integral);
+ __ mov(rscratch2, r0);
+ __ pop_call_clobbered_registers();
+ __ mov(dst, rscratch2);
+
+ __ bind(done);
+ __ leave();
+ __ bind(is_null);
+}
+
void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
if (ShenandoahStoreValEnqueueBarrier) {
// Save possibly live regs.
@@ -309,15 +343,25 @@
void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Address src, Register tmp1, Register tmp_thread) {
bool on_oop = type == T_OBJECT || type == T_ARRAY;
+ bool not_in_heap = (decorators & IN_NATIVE) != 0;
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
bool on_reference = on_weak || on_phantom;
+ bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
if (on_oop) {
- load_reference_barrier(masm, dst, tmp1);
-
- if (ShenandoahKeepAliveBarrier && on_reference) {
+ if (not_in_heap) {
+ if (ShenandoahHeap::heap()->is_traversal_mode()) {
+ load_reference_barrier(masm, dst, tmp1);
+ keep_alive = true;
+ } else {
+ load_reference_barrier_native(masm, dst, tmp1);
+ }
+ } else {
+ load_reference_barrier(masm, dst, tmp1);
+ }
+ if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
__ enter();
satb_write_barrier_pre(masm /* masm */,
noreg /* obj */,
@@ -469,9 +513,7 @@
__ mov(res, obj);
}
// Check for null.
- if (stub->needs_null_check()) {
- __ cbz(res, done);
- }
+ __ cbz(res, done);
load_reference_barrier_not_null(ce->masm(), res, rscratch1);
@@ -572,7 +614,7 @@
__ push_call_clobbered_registers();
- __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT));
+ __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier));
__ blrt(lr, 1, 0, MacroAssembler::ret_type_integral);
__ mov(rscratch1, r0);
__ pop_call_clobbered_registers();
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
*
* 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
@@ -58,6 +58,7 @@
void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg);
void load_reference_barrier(MacroAssembler* masm, Register dst, Register tmp);
void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Register tmp);
+ void load_reference_barrier_native(MacroAssembler* masm, Register dst, Register tmp);
address generate_shenandoah_lrb(StubCodeGenerator* cgen);
--- a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad Mon Jul 22 11:08:27 2019 +0530
@@ -61,7 +61,7 @@
//
// Execute ZGC load barrier (strong) slow path
//
-instruct loadBarrierSlowReg(iRegP dst, memory mem, rFlagsReg cr,
+instruct loadBarrierSlowReg(iRegP dst, memory src, rFlagsReg cr,
vRegD_V0 v0, vRegD_V1 v1, vRegD_V2 v2, vRegD_V3 v3, vRegD_V4 v4,
vRegD_V5 v5, vRegD_V6 v6, vRegD_V7 v7, vRegD_V8 v8, vRegD_V9 v9,
vRegD_V10 v10, vRegD_V11 v11, vRegD_V12 v12, vRegD_V13 v13, vRegD_V14 v14,
@@ -69,20 +69,22 @@
vRegD_V20 v20, vRegD_V21 v21, vRegD_V22 v22, vRegD_V23 v23, vRegD_V24 v24,
vRegD_V25 v25, vRegD_V26 v26, vRegD_V27 v27, vRegD_V28 v28, vRegD_V29 v29,
vRegD_V30 v30, vRegD_V31 v31) %{
- match(Set dst (LoadBarrierSlowReg mem));
+ match(Set dst (LoadBarrierSlowReg src dst));
predicate(!n->as_LoadBarrierSlowReg()->is_weak());
- effect(DEF dst, KILL cr,
+ effect(KILL cr,
KILL v0, KILL v1, KILL v2, KILL v3, KILL v4, KILL v5, KILL v6, KILL v7,
KILL v8, KILL v9, KILL v10, KILL v11, KILL v12, KILL v13, KILL v14,
KILL v15, KILL v16, KILL v17, KILL v18, KILL v19, KILL v20, KILL v21,
KILL v22, KILL v23, KILL v24, KILL v25, KILL v26, KILL v27, KILL v28,
KILL v29, KILL v30, KILL v31);
- format %{"LoadBarrierSlowReg $dst, $mem" %}
+ format %{ "lea $dst, $src\n\t"
+ "call #ZLoadBarrierSlowPath" %}
+
ins_encode %{
- z_load_barrier_slow_reg(_masm, $dst$$Register, $mem$$base$$Register,
- $mem$$index, $mem$$scale, $mem$$disp, false);
+ z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$base$$Register,
+ $src$$index, $src$$scale, $src$$disp, false);
%}
ins_pipe(pipe_slow);
%}
@@ -90,7 +92,7 @@
//
// Execute ZGC load barrier (weak) slow path
//
-instruct loadBarrierWeakSlowReg(iRegP dst, memory mem, rFlagsReg cr,
+instruct loadBarrierWeakSlowReg(iRegP dst, memory src, rFlagsReg cr,
vRegD_V0 v0, vRegD_V1 v1, vRegD_V2 v2, vRegD_V3 v3, vRegD_V4 v4,
vRegD_V5 v5, vRegD_V6 v6, vRegD_V7 v7, vRegD_V8 v8, vRegD_V9 v9,
vRegD_V10 v10, vRegD_V11 v11, vRegD_V12 v12, vRegD_V13 v13, vRegD_V14 v14,
@@ -98,20 +100,22 @@
vRegD_V20 v20, vRegD_V21 v21, vRegD_V22 v22, vRegD_V23 v23, vRegD_V24 v24,
vRegD_V25 v25, vRegD_V26 v26, vRegD_V27 v27, vRegD_V28 v28, vRegD_V29 v29,
vRegD_V30 v30, vRegD_V31 v31) %{
- match(Set dst (LoadBarrierSlowReg mem));
+ match(Set dst (LoadBarrierSlowReg src dst));
predicate(n->as_LoadBarrierSlowReg()->is_weak());
- effect(DEF dst, KILL cr,
+ effect(KILL cr,
KILL v0, KILL v1, KILL v2, KILL v3, KILL v4, KILL v5, KILL v6, KILL v7,
KILL v8, KILL v9, KILL v10, KILL v11, KILL v12, KILL v13, KILL v14,
KILL v15, KILL v16, KILL v17, KILL v18, KILL v19, KILL v20, KILL v21,
KILL v22, KILL v23, KILL v24, KILL v25, KILL v26, KILL v27, KILL v28,
KILL v29, KILL v30, KILL v31);
- format %{"LoadBarrierWeakSlowReg $dst, $mem" %}
+ format %{ "lea $dst, $src\n\t"
+ "call #ZLoadBarrierSlowPath" %}
+
ins_encode %{
- z_load_barrier_slow_reg(_masm, $dst$$Register, $mem$$base$$Register,
- $mem$$index, $mem$$scale, $mem$$disp, true);
+ z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$base$$Register,
+ $src$$index, $src$$scale, $src$$disp, true);
%}
ins_pipe(pipe_slow);
%}
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -800,6 +800,7 @@
#endif
// Class initialization barrier for static methods
+ address c2i_no_clinit_check_entry = NULL;
if (VM_Version::supports_fast_class_init_checks()) {
Label L_skip_barrier;
@@ -812,13 +813,15 @@
__ load_method_holder(rscratch2, rmethod);
__ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+
__ bind(L_skip_barrier);
+ c2i_no_clinit_check_entry = __ pc();
}
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
__ flush();
- return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1277,6 +1277,7 @@
c2i_entry = __ pc();
// Class initialization barrier for static methods
+ address c2i_no_clinit_check_entry = NULL;
if (VM_Version::supports_fast_class_init_checks()) {
Label L_skip_barrier;
@@ -1295,11 +1296,12 @@
__ bctr();
__ bind(L_skip_barrier);
+ c2i_no_clinit_check_entry = __ pc();
}
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, call_interpreter, ientry);
- return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
}
#ifdef COMPILER2
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -2713,6 +2713,7 @@
address c2i_entry = __ pc();
// Class initialization barrier for static methods
+ address c2i_no_clinit_check_entry = NULL;
if (VM_Version::supports_fast_class_init_checks()) {
Label L_skip_barrier;
@@ -2729,11 +2730,12 @@
__ z_br(klass);
__ bind(L_skip_barrier);
+ c2i_no_clinit_check_entry = __ pc();
}
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
- return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
}
// This function returns the adjust size (in number of words) to a c2i adapter
--- a/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -110,7 +110,7 @@
__ xchg(access.resolved_addr(), result, result, LIR_OprFact::illegalOpr);
if (access.is_oop()) {
- result = load_reference_barrier(access.gen(), result, access.access_emit_info(), true);
+ result = load_reference_barrier(access.gen(), result);
if (ShenandoahSATBBarrier) {
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr,
result /* pre_val */);
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/shenandoahForwarding.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahRuntime.hpp"
@@ -69,7 +69,7 @@
}
#endif
- if (ShenandoahSATBBarrier && !dest_uninitialized && !ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc()) {
+ if (ShenandoahSATBBarrier && !dest_uninitialized) {
Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
assert_different_registers(dst, count, thread); // we don't care about src here?
#ifndef _LP64
@@ -401,6 +401,86 @@
#endif
}
+void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst) {
+ if (!ShenandoahLoadRefBarrier) {
+ return;
+ }
+
+ Label done;
+ Label not_null;
+ Label slow_path;
+
+ // null check
+ __ testptr(dst, dst);
+ __ jcc(Assembler::notZero, not_null);
+ __ jmp(done);
+ __ bind(not_null);
+
+
+#ifdef _LP64
+ Register thread = r15_thread;
+#else
+ Register thread = rcx;
+ if (thread == dst) {
+ thread = rbx;
+ }
+ __ push(thread);
+ __ get_thread(thread);
+#endif
+ assert_different_registers(dst, thread);
+
+ Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
+ __ testb(gc_state, ShenandoahHeap::EVACUATION);
+#ifndef _LP64
+ __ pop(thread);
+#endif
+ __ jccb(Assembler::notZero, slow_path);
+ __ jmp(done);
+ __ bind(slow_path);
+
+ if (dst != rax) {
+ __ xchgptr(dst, rax); // Move obj into rax and save rax into obj.
+ }
+ __ push(rcx);
+ __ push(rdx);
+ __ push(rdi);
+ __ push(rsi);
+#ifdef _LP64
+ __ push(r8);
+ __ push(r9);
+ __ push(r10);
+ __ push(r11);
+ __ push(r12);
+ __ push(r13);
+ __ push(r14);
+ __ push(r15);
+#endif
+
+ __ movptr(rdi, rax);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), rdi);
+
+#ifdef _LP64
+ __ pop(r15);
+ __ pop(r14);
+ __ pop(r13);
+ __ pop(r12);
+ __ pop(r11);
+ __ pop(r10);
+ __ pop(r9);
+ __ pop(r8);
+#endif
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rdx);
+ __ pop(rcx);
+
+ if (dst != rax) {
+ __ xchgptr(rax, dst); // Swap back obj with rax.
+ }
+
+ __ bind(done);
+}
+
void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
if (ShenandoahStoreValEnqueueBarrier) {
storeval_barrier_impl(masm, dst, tmp);
@@ -457,12 +537,24 @@
bool on_oop = type == T_OBJECT || type == T_ARRAY;
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
+ bool not_in_heap = (decorators & IN_NATIVE) != 0;
bool on_reference = on_weak || on_phantom;
- BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
+ bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;
+
+ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
if (on_oop) {
- load_reference_barrier(masm, dst);
+ if (not_in_heap) {
+ if (ShenandoahHeap::heap()->is_traversal_mode()) {
+ load_reference_barrier(masm, dst);
+ keep_alive = true;
+ } else {
+ load_reference_barrier_native(masm, dst);
+ }
+ } else {
+ load_reference_barrier(masm, dst);
+ }
- if (ShenandoahKeepAliveBarrier && on_reference) {
+ if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
assert_different_registers(dst, tmp1, tmp_thread);
NOT_LP64(__ get_thread(thread));
@@ -788,10 +880,8 @@
}
// Check for null.
- if (stub->needs_null_check()) {
- __ testptr(res, res);
- __ jcc(Assembler::zero, done);
- }
+ __ testptr(res, res);
+ __ jcc(Assembler::zero, done);
load_reference_barrier_not_null(ce->masm(), res);
@@ -943,7 +1033,7 @@
save_vector_registers(cgen->assembler());
__ movptr(rdi, rax);
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), rdi);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rdi);
restore_vector_registers(cgen->assembler());
#ifdef _LP64
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
*
* 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
@@ -78,6 +78,7 @@
#endif
void load_reference_barrier(MacroAssembler* masm, Register dst);
+ void load_reference_barrier_native(MacroAssembler* masm, Register dst);
void cmpxchg_oop(MacroAssembler* masm,
Register res, Address addr, Register oldval, Register newval,
--- a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad Mon Jul 22 11:08:27 2019 +0530
@@ -45,32 +45,31 @@
// For XMM and YMM enabled processors
instruct zLoadBarrierSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
- rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
+ match(Set dst (LoadBarrierSlowReg src dst));
+ predicate(UseAVX <= 2 && !n->as_LoadBarrierSlowReg()->is_weak());
- match(Set dst (LoadBarrierSlowReg src));
- predicate((UseAVX <= 2) && !n->as_LoadBarrierSlowReg()->is_weak());
-
- effect(DEF dst, KILL cr,
+ effect(KILL cr,
KILL x0, KILL x1, KILL x2, KILL x3,
KILL x4, KILL x5, KILL x6, KILL x7,
KILL x8, KILL x9, KILL x10, KILL x11,
KILL x12, KILL x13, KILL x14, KILL x15);
- format %{ "zLoadBarrierSlowRegXmmAndYmm $dst, $src" %}
+ format %{ "lea $dst, $src\n\t"
+ "call #ZLoadBarrierSlowPath" %}
ins_encode %{
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
%}
-
ins_pipe(pipe_slow);
%}
// For ZMM enabled processors
instruct zLoadBarrierSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
- rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
@@ -79,10 +78,10 @@
rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
- match(Set dst (LoadBarrierSlowReg src));
- predicate((UseAVX == 3) && !n->as_LoadBarrierSlowReg()->is_weak());
+ match(Set dst (LoadBarrierSlowReg src dst));
+ predicate(UseAVX == 3 && !n->as_LoadBarrierSlowReg()->is_weak());
- effect(DEF dst, KILL cr,
+ effect(KILL cr,
KILL x0, KILL x1, KILL x2, KILL x3,
KILL x4, KILL x5, KILL x6, KILL x7,
KILL x8, KILL x9, KILL x10, KILL x11,
@@ -92,43 +91,42 @@
KILL x24, KILL x25, KILL x26, KILL x27,
KILL x28, KILL x29, KILL x30, KILL x31);
- format %{ "zLoadBarrierSlowRegZmm $dst, $src" %}
+ format %{ "lea $dst, $src\n\t"
+ "call #ZLoadBarrierSlowPath" %}
ins_encode %{
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
%}
-
ins_pipe(pipe_slow);
%}
// For XMM and YMM enabled processors
instruct zLoadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
- rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
+ match(Set dst (LoadBarrierSlowReg src dst));
+ predicate(UseAVX <= 2 && n->as_LoadBarrierSlowReg()->is_weak());
- match(Set dst (LoadBarrierSlowReg src));
- predicate((UseAVX <= 2) && n->as_LoadBarrierSlowReg()->is_weak());
-
- effect(DEF dst, KILL cr,
+ effect(KILL cr,
KILL x0, KILL x1, KILL x2, KILL x3,
KILL x4, KILL x5, KILL x6, KILL x7,
KILL x8, KILL x9, KILL x10, KILL x11,
KILL x12, KILL x13, KILL x14, KILL x15);
- format %{ "zLoadBarrierWeakSlowRegXmmAndYmm $dst, $src" %}
+ format %{ "lea $dst, $src\n\t"
+ "call #ZLoadBarrierSlowPath" %}
ins_encode %{
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
%}
-
ins_pipe(pipe_slow);
%}
// For ZMM enabled processors
instruct zLoadBarrierWeakSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
- rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
@@ -137,10 +135,10 @@
rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
- match(Set dst (LoadBarrierSlowReg src));
- predicate((UseAVX == 3) && n->as_LoadBarrierSlowReg()->is_weak());
+ match(Set dst (LoadBarrierSlowReg src dst));
+ predicate(UseAVX == 3 && n->as_LoadBarrierSlowReg()->is_weak());
- effect(DEF dst, KILL cr,
+ effect(KILL cr,
KILL x0, KILL x1, KILL x2, KILL x3,
KILL x4, KILL x5, KILL x6, KILL x7,
KILL x8, KILL x9, KILL x10, KILL x11,
@@ -150,12 +148,12 @@
KILL x24, KILL x25, KILL x26, KILL x27,
KILL x28, KILL x29, KILL x30, KILL x31);
- format %{ "zLoadBarrierWeakSlowRegZmm $dst, $src" %}
+ format %{ "lea $dst, $src\n\t"
+ "call #ZLoadBarrierSlowPath" %}
ins_encode %{
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
%}
-
ins_pipe(pipe_slow);
%}
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -971,10 +971,8 @@
address c2i_entry = __ pc();
- BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->c2i_entry_barrier(masm);
-
// Class initialization barrier for static methods
+ address c2i_no_clinit_check_entry = NULL;
if (VM_Version::supports_fast_class_init_checks()) {
Label L_skip_barrier;
Register method = rbx;
@@ -993,12 +991,16 @@
__ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
__ bind(L_skip_barrier);
+ c2i_no_clinit_check_entry = __ pc();
}
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->c2i_entry_barrier(masm);
+
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
__ flush();
- return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
--- a/src/hotspot/cpu/x86/x86_64.ad Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/cpu/x86/x86_64.ad Mon Jul 22 11:08:27 2019 +0530
@@ -5543,7 +5543,7 @@
ins_pipe( pipe_slow );
%}
-instruct maxF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{
+instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{
predicate(UseAVX > 0 && n->is_reduction());
match(Set dst (MaxF a b));
effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
@@ -5579,7 +5579,7 @@
ins_pipe( pipe_slow );
%}
-instruct maxD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{
+instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{
predicate(UseAVX > 0 && n->is_reduction());
match(Set dst (MaxD a b));
effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
@@ -5615,7 +5615,7 @@
ins_pipe( pipe_slow );
%}
-instruct minF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{
+instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{
predicate(UseAVX > 0 && n->is_reduction());
match(Set dst (MinF a b));
effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
@@ -5651,7 +5651,7 @@
ins_pipe( pipe_slow );
%}
-instruct minD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{
+instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{
predicate(UseAVX > 0 && n->is_reduction());
match(Set dst (MinD a b));
effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
--- a/src/hotspot/os/aix/attachListener_aix.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/aix/attachListener_aix.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -71,17 +71,7 @@
// the file descriptor for the listening socket
static int _listener;
- static void set_path(char* path) {
- if (path == NULL) {
- _has_path = false;
- } else {
- strncpy(_path, path, UNIX_PATH_MAX);
- _path[UNIX_PATH_MAX-1] = '\0';
- _has_path = true;
- }
- }
-
- static void set_listener(int s) { _listener = s; }
+ static bool _atexit_registered;
// reads a request from the given connected socket
static AixAttachOperation* read_request(int s);
@@ -94,6 +84,19 @@
ATTACH_ERROR_BADVERSION = 101 // error codes
};
+ static void set_path(char* path) {
+ if (path == NULL) {
+ _path[0] = '\0';
+ _has_path = false;
+ } else {
+ strncpy(_path, path, UNIX_PATH_MAX);
+ _path[UNIX_PATH_MAX-1] = '\0';
+ _has_path = true;
+ }
+ }
+
+ static void set_listener(int s) { _listener = s; }
+
// initialize the listener, returns 0 if okay
static int init();
@@ -130,6 +133,7 @@
char AixAttachListener::_path[UNIX_PATH_MAX];
bool AixAttachListener::_has_path;
int AixAttachListener::_listener = -1;
+bool AixAttachListener::_atexit_registered = false;
// Shutdown marker to prevent accept blocking during clean-up
bool AixAttachListener::_shutdown = false;
@@ -177,17 +181,15 @@
// should be sufficient for cleanup.
extern "C" {
static void listener_cleanup() {
- static int cleanup_done;
- if (!cleanup_done) {
- cleanup_done = 1;
- AixAttachListener::set_shutdown(true);
- int s = AixAttachListener::listener();
- if (s != -1) {
- ::shutdown(s, 2);
- }
- if (AixAttachListener::has_path()) {
- ::unlink(AixAttachListener::path());
- }
+ AixAttachListener::set_shutdown(true);
+ int s = AixAttachListener::listener();
+ if (s != -1) {
+ AixAttachListener::set_listener(-1);
+ ::shutdown(s, 2);
+ }
+ if (AixAttachListener::has_path()) {
+ ::unlink(AixAttachListener::path());
+ AixAttachListener::set_path(NULL);
}
}
}
@@ -200,7 +202,10 @@
int listener; // listener socket (file descriptor)
// register function to cleanup
- ::atexit(listener_cleanup);
+ if (!_atexit_registered) {
+ _atexit_registered = true;
+ ::atexit(listener_cleanup);
+ }
int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id());
@@ -515,6 +520,26 @@
return ret_code;
}
+bool AttachListener::check_socket_file() {
+ int ret;
+ struct stat64 st;
+ ret = stat64(AixAttachListener::path(), &st);
+ if (ret == -1) { // need to restart attach listener.
+ log_debug(attach)("Socket file %s does not exist - Restart Attach Listener",
+ AixAttachListener::path());
+
+ listener_cleanup();
+
+ // wait to terminate current attach listener instance...
+ while (AttachListener::transit_state(AL_INITIALIZING,
+ AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+ os::naked_yield();
+ }
+ return is_init_trigger();
+ }
+ return false;
+}
+
// Attach Listener is started lazily except in the case when
// +ReduseSignalUsage is used
bool AttachListener::init_at_startup() {
--- a/src/hotspot/os/aix/loadlib_aix.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/aix/loadlib_aix.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -207,7 +207,7 @@
}
}
- trcVerbose("loadquery buffer size is %llu.", buflen);
+ trcVerbose("loadquery buffer size is " SIZE_FORMAT ".", buflen);
// Iterate over the loadquery result. For details see sys/ldr.h on AIX.
ldi = (struct ld_info*) buffer;
@@ -264,7 +264,7 @@
e->info.is_in_vm = true;
}
- trcVerbose("entry: %p %llu, %p %llu, %s %s %s, %d",
+ trcVerbose("entry: %p " SIZE_FORMAT ", %p " SIZE_FORMAT ", %s %s %s, %d",
e->info.text, e->info.text_len,
e->info.data, e->info.data_len,
e->info.path, e->info.shortname,
--- a/src/hotspot/os/aix/os_aix.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/aix/os_aix.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -4075,7 +4075,7 @@
assert(minor > 0, "invalid OS release");
_os_version = (major << 24) | (minor << 16);
char ver_str[20] = {0};
- char *name_str = "unknown OS";
+ const char* name_str = "unknown OS";
if (strcmp(uts.sysname, "OS400") == 0) {
// We run on AS/400 PASE. We do not support versions older than V5R4M0.
_on_pase = 1;
@@ -4086,19 +4086,19 @@
name_str = "OS/400 (pase)";
jio_snprintf(ver_str, sizeof(ver_str), "%u.%u", major, minor);
} else if (strcmp(uts.sysname, "AIX") == 0) {
- // We run on AIX. We do not support versions older than AIX 5.3.
+ // We run on AIX. We do not support versions older than AIX 7.1.
_on_pase = 0;
// Determine detailed AIX version: Version, Release, Modification, Fix Level.
odmWrapper::determine_os_kernel_version(&_os_version);
- if (os_version_short() < 0x0503) {
- trcVerbose("AIX release older than AIX 5.3 not supported.");
+ if (os_version_short() < 0x0701) {
+ trcVerbose("AIX releases older than AIX 7.1 are not supported.");
assert(false, "AIX release too old.");
}
name_str = "AIX";
jio_snprintf(ver_str, sizeof(ver_str), "%u.%u.%u.%u",
major, minor, (_os_version >> 8) & 0xFF, _os_version & 0xFF);
} else {
- assert(false, name_str);
+ assert(false, "%s", name_str);
}
trcVerbose("We run on %s %s", name_str, ver_str);
}
--- a/src/hotspot/os/aix/perfMemory_aix.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/aix/perfMemory_aix.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1111,7 +1111,7 @@
if ((statbuf.st_size == 0) ||
((size_t)statbuf.st_size % os::vm_page_size() != 0)) {
- THROW_MSG_0(vmSymbols::java_lang_Exception(),
+ THROW_MSG_0(vmSymbols::java_io_IOException(),
"Invalid PerfMemory size");
}
--- a/src/hotspot/os/bsd/attachListener_bsd.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/bsd/attachListener_bsd.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,17 +68,7 @@
// the file descriptor for the listening socket
static int _listener;
- static void set_path(char* path) {
- if (path == NULL) {
- _has_path = false;
- } else {
- strncpy(_path, path, UNIX_PATH_MAX);
- _path[UNIX_PATH_MAX-1] = '\0';
- _has_path = true;
- }
- }
-
- static void set_listener(int s) { _listener = s; }
+ static bool _atexit_registered;
// reads a request from the given connected socket
static BsdAttachOperation* read_request(int s);
@@ -91,6 +81,19 @@
ATTACH_ERROR_BADVERSION = 101 // error codes
};
+ static void set_path(char* path) {
+ if (path == NULL) {
+ _path[0] = '\0';
+ _has_path = false;
+ } else {
+ strncpy(_path, path, UNIX_PATH_MAX);
+ _path[UNIX_PATH_MAX-1] = '\0';
+ _has_path = true;
+ }
+ }
+
+ static void set_listener(int s) { _listener = s; }
+
// initialize the listener, returns 0 if okay
static int init();
@@ -124,6 +127,7 @@
char BsdAttachListener::_path[UNIX_PATH_MAX];
bool BsdAttachListener::_has_path;
int BsdAttachListener::_listener = -1;
+bool BsdAttachListener::_atexit_registered = false;
// Supporting class to help split a buffer into individual components
class ArgumentIterator : public StackObj {
@@ -158,16 +162,15 @@
// bound too.
extern "C" {
static void listener_cleanup() {
- static int cleanup_done;
- if (!cleanup_done) {
- cleanup_done = 1;
- int s = BsdAttachListener::listener();
- if (s != -1) {
- ::close(s);
- }
- if (BsdAttachListener::has_path()) {
- ::unlink(BsdAttachListener::path());
- }
+ int s = BsdAttachListener::listener();
+ if (s != -1) {
+ BsdAttachListener::set_listener(-1);
+ ::shutdown(s, SHUT_RDWR);
+ ::close(s);
+ }
+ if (BsdAttachListener::has_path()) {
+ ::unlink(BsdAttachListener::path());
+ BsdAttachListener::set_path(NULL);
}
}
}
@@ -180,7 +183,10 @@
int listener; // listener socket (file descriptor)
// register function to cleanup
- ::atexit(listener_cleanup);
+ if (!_atexit_registered) {
+ _atexit_registered = true;
+ ::atexit(listener_cleanup);
+ }
int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id());
@@ -485,6 +491,28 @@
return ret_code;
}
+bool AttachListener::check_socket_file() {
+ int ret;
+ struct stat st;
+ ret = stat(BsdAttachListener::path(), &st);
+ if (ret == -1) { // need to restart attach listener.
+ log_debug(attach)("Socket file %s does not exist - Restart Attach Listener",
+ BsdAttachListener::path());
+
+ listener_cleanup();
+
+ // wait to terminate current attach listener instance...
+
+ while (AttachListener::transit_state(AL_INITIALIZING,
+
+ AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+ os::naked_yield();
+ }
+ return is_init_trigger();
+ }
+ return false;
+}
+
// Attach Listener is started lazily except in the case when
// +ReduseSignalUsage is used
bool AttachListener::init_at_startup() {
--- a/src/hotspot/os/bsd/perfMemory_bsd.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/bsd/perfMemory_bsd.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1028,7 +1028,7 @@
if ((statbuf.st_size == 0) ||
((size_t)statbuf.st_size % os::vm_page_size() != 0)) {
- THROW_MSG_0(vmSymbols::java_lang_Exception(),
+ THROW_MSG_0(vmSymbols::java_io_IOException(),
"Invalid PerfMemory size");
}
--- a/src/hotspot/os/linux/attachListener_linux.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/linux/attachListener_linux.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,17 +69,7 @@
// the file descriptor for the listening socket
static int _listener;
- static void set_path(char* path) {
- if (path == NULL) {
- _has_path = false;
- } else {
- strncpy(_path, path, UNIX_PATH_MAX);
- _path[UNIX_PATH_MAX-1] = '\0';
- _has_path = true;
- }
- }
-
- static void set_listener(int s) { _listener = s; }
+ static bool _atexit_registered;
// reads a request from the given connected socket
static LinuxAttachOperation* read_request(int s);
@@ -92,6 +82,19 @@
ATTACH_ERROR_BADVERSION = 101 // error codes
};
+ static void set_path(char* path) {
+ if (path == NULL) {
+ _path[0] = '\0';
+ _has_path = false;
+ } else {
+ strncpy(_path, path, UNIX_PATH_MAX);
+ _path[UNIX_PATH_MAX-1] = '\0';
+ _has_path = true;
+ }
+ }
+
+ static void set_listener(int s) { _listener = s; }
+
// initialize the listener, returns 0 if okay
static int init();
@@ -125,6 +128,7 @@
char LinuxAttachListener::_path[UNIX_PATH_MAX];
bool LinuxAttachListener::_has_path;
int LinuxAttachListener::_listener = -1;
+bool LinuxAttachListener::_atexit_registered = false;
// Supporting class to help split a buffer into individual components
class ArgumentIterator : public StackObj {
@@ -159,16 +163,15 @@
// bound too.
extern "C" {
static void listener_cleanup() {
- static int cleanup_done;
- if (!cleanup_done) {
- cleanup_done = 1;
- int s = LinuxAttachListener::listener();
- if (s != -1) {
- ::close(s);
- }
- if (LinuxAttachListener::has_path()) {
- ::unlink(LinuxAttachListener::path());
- }
+ int s = LinuxAttachListener::listener();
+ if (s != -1) {
+ LinuxAttachListener::set_listener(-1);
+ ::shutdown(s, SHUT_RDWR);
+ ::close(s);
+ }
+ if (LinuxAttachListener::has_path()) {
+ ::unlink(LinuxAttachListener::path());
+ LinuxAttachListener::set_path(NULL);
}
}
}
@@ -181,7 +184,10 @@
int listener; // listener socket (file descriptor)
// register function to cleanup
- ::atexit(listener_cleanup);
+ if (!_atexit_registered) {
+ _atexit_registered = true;
+ ::atexit(listener_cleanup);
+ }
int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id());
@@ -485,6 +491,26 @@
return ret_code;
}
+bool AttachListener::check_socket_file() {
+ int ret;
+ struct stat64 st;
+ ret = stat64(LinuxAttachListener::path(), &st);
+ if (ret == -1) { // need to restart attach listener.
+ log_debug(attach)("Socket file %s does not exist - Restart Attach Listener",
+ LinuxAttachListener::path());
+
+ listener_cleanup();
+
+ // wait to terminate current attach listener instance...
+ while (AttachListener::transit_state(AL_INITIALIZING,
+ AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+ os::naked_yield();
+ }
+ return is_init_trigger();
+ }
+ return false;
+}
+
// Attach Listener is started lazily except in the case when
// +ReduseSignalUsage is used
bool AttachListener::init_at_startup() {
--- a/src/hotspot/os/linux/globals_linux.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/linux/globals_linux.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -64,9 +64,13 @@
\
product(bool, PreferContainerQuotaForCPUCount, true, \
"Calculate the container CPU availability based on the value" \
- " of quotas (if set), when true. Otherwise, use the CPU" \
+ " of quotas (if set), when true. Otherwise, use the CPU" \
" shares value, provided it is less than quota.") \
\
+ product(bool, AdjustStackSizeForTLS, false, \
+ "Increase the thread stack size to include space for glibc " \
+ "static thread-local storage (TLS) if true") \
+ \
diagnostic(bool, DumpPrivateMappingsInCore, true, \
"If true, sets bit 2 of /proc/PID/coredump_filter, thus " \
"resulting in file-backed private mappings of the process to "\
--- a/src/hotspot/os/linux/os_linux.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/linux/os_linux.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -84,6 +84,7 @@
# include <sys/select.h>
# include <pthread.h>
# include <signal.h>
+# include <endian.h>
# include <errno.h>
# include <dlfcn.h>
# include <stdio.h>
@@ -800,6 +801,73 @@
return 0;
}
+// On Linux, glibc places static TLS blocks (for __thread variables) on
+// the thread stack. This decreases the stack size actually available
+// to threads.
+//
+// For large static TLS sizes, this may cause threads to malfunction due
+// to insufficient stack space. This is a well-known issue in glibc:
+// http://sourceware.org/bugzilla/show_bug.cgi?id=11787.
+//
+// As a workaround, we call a private but assumed-stable glibc function,
+// __pthread_get_minstack() to obtain the minstack size and derive the
+// static TLS size from it. We then increase the user requested stack
+// size by this TLS size.
+//
+// Due to compatibility concerns, this size adjustment is opt-in and
+// controlled via AdjustStackSizeForTLS.
+typedef size_t (*GetMinStack)(const pthread_attr_t *attr);
+
+GetMinStack _get_minstack_func = NULL;
+
+static void get_minstack_init() {
+ _get_minstack_func =
+ (GetMinStack)dlsym(RTLD_DEFAULT, "__pthread_get_minstack");
+ log_info(os, thread)("Lookup of __pthread_get_minstack %s",
+ _get_minstack_func == NULL ? "failed" : "succeeded");
+}
+
+// Returns the size of the static TLS area glibc puts on thread stacks.
+// The value is cached on first use, which occurs when the first thread
+// is created during VM initialization.
+static size_t get_static_tls_area_size(const pthread_attr_t *attr) {
+ size_t tls_size = 0;
+ if (_get_minstack_func != NULL) {
+ // Obtain the pthread minstack size by calling __pthread_get_minstack.
+ size_t minstack_size = _get_minstack_func(attr);
+
+ // Remove non-TLS area size included in minstack size returned
+ // by __pthread_get_minstack() to get the static TLS size.
+ // In glibc before 2.27, minstack size includes guard_size.
+ // In glibc 2.27 and later, guard_size is automatically added
+ // to the stack size by pthread_create and is no longer included
+ // in minstack size. In both cases, the guard_size is taken into
+ // account, so there is no need to adjust the result for that.
+ //
+ // Although __pthread_get_minstack() is a private glibc function,
+ // it is expected to have a stable behavior across future glibc
+ // versions while glibc still allocates the static TLS blocks off
+ // the stack. Following is glibc 2.28 __pthread_get_minstack():
+ //
+ // size_t
+ // __pthread_get_minstack (const pthread_attr_t *attr)
+ // {
+ // return GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN;
+ // }
+ //
+ //
+ // The following 'minstack_size > os::vm_page_size() + PTHREAD_STACK_MIN'
+ // if check is done for precaution.
+ if (minstack_size > (size_t)os::vm_page_size() + PTHREAD_STACK_MIN) {
+ tls_size = minstack_size - os::vm_page_size() - PTHREAD_STACK_MIN;
+ }
+ }
+
+ log_info(os, thread)("Stack size adjustment for TLS is " SIZE_FORMAT,
+ tls_size);
+ return tls_size;
+}
+
bool os::create_thread(Thread* thread, ThreadType thr_type,
size_t req_stack_size) {
assert(thread->osthread() == NULL, "caller responsible");
@@ -825,7 +893,7 @@
// Calculate stack size if it's not specified by caller.
size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
- // In the Linux NPTL pthread implementation the guard size mechanism
+ // In glibc versions prior to 2.7 the guard size mechanism
// is not implemented properly. The posix standard requires adding
// the size of the guard pages to the stack size, instead Linux
// takes the space out of 'stacksize'. Thus we adapt the requested
@@ -833,17 +901,27 @@
// behaviour. However, be careful not to end up with a size
// of zero due to overflow. Don't add the guard page in that case.
size_t guard_size = os::Linux::default_guard_size(thr_type);
- if (stack_size <= SIZE_MAX - guard_size) {
- stack_size += guard_size;
+ // Configure glibc guard page. Must happen before calling
+ // get_static_tls_area_size(), which uses the guard_size.
+ pthread_attr_setguardsize(&attr, guard_size);
+
+ size_t stack_adjust_size = 0;
+ if (AdjustStackSizeForTLS) {
+ // Adjust the stack_size for on-stack TLS - see get_static_tls_area_size().
+ stack_adjust_size += get_static_tls_area_size(&attr);
+ } else {
+ stack_adjust_size += guard_size;
+ }
+
+ stack_adjust_size = align_up(stack_adjust_size, os::vm_page_size());
+ if (stack_size <= SIZE_MAX - stack_adjust_size) {
+ stack_size += stack_adjust_size;
}
assert(is_aligned(stack_size, os::vm_page_size()), "stack_size not aligned");
int status = pthread_attr_setstacksize(&attr, stack_size);
assert_status(status == 0, status, "pthread_attr_setstacksize");
- // Configure glibc guard page.
- pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
-
ThreadState state;
{
@@ -1747,11 +1825,26 @@
return NULL;
}
+ if (elf_head.e_ident[EI_DATA] != LITTLE_ENDIAN_ONLY(ELFDATA2LSB) BIG_ENDIAN_ONLY(ELFDATA2MSB)) {
+ // handle invalid/out of range endianness values
+ if (elf_head.e_ident[EI_DATA] == 0 || elf_head.e_ident[EI_DATA] > 2) {
+ return NULL;
+ }
+
+#if defined(VM_LITTLE_ENDIAN)
+ // VM is LE, shared object BE
+ elf_head.e_machine = be16toh(elf_head.e_machine);
+#else
+ // VM is BE, shared object LE
+ elf_head.e_machine = le16toh(elf_head.e_machine);
+#endif
+ }
+
typedef struct {
Elf32_Half code; // Actual value as defined in elf.h
Elf32_Half compat_class; // Compatibility of archs at VM's sense
unsigned char elf_class; // 32 or 64 bit
- unsigned char endianess; // MSB or LSB
+ unsigned char endianness; // MSB or LSB
char* name; // String representation
} arch_t;
@@ -1778,8 +1871,9 @@
{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
{EM_SH, EM_SH, ELFCLASS32, ELFDATA2MSB, (char*)"SuperH BE"},
#endif
- {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
- {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
+ {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
+ // we only support 64 bit z architecture
+ {EM_S390, EM_S390, ELFCLASS64, ELFDATA2MSB, (char*)"IBM System/390"},
{EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
{EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
{EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
@@ -1825,7 +1919,7 @@
AARCH64, ALPHA, ARM, AMD64, IA32, IA64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, S390, SH, __sparc
#endif
- // Identify compatability class for VM's architecture and library's architecture
+ // Identify compatibility class for VM's architecture and library's architecture
// Obtain string descriptions for architectures
arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
@@ -1849,29 +1943,35 @@
return NULL;
}
- if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
- ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
- return NULL;
- }
-
-#ifndef S390
- if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
- ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
- return NULL;
- }
-#endif // !S390
-
if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
- if (lib_arch.name!=NULL) {
+ if (lib_arch.name != NULL) {
::snprintf(diag_msg_buf, diag_msg_max_length-1,
- " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
+ " (Possible cause: can't load %s .so on a %s platform)",
lib_arch.name, arch_array[running_arch_index].name);
} else {
::snprintf(diag_msg_buf, diag_msg_max_length-1,
- " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
- lib_arch.code,
- arch_array[running_arch_index].name);
+ " (Possible cause: can't load this .so (machine code=0x%x) on a %s platform)",
+ lib_arch.code, arch_array[running_arch_index].name);
}
+ return NULL;
+ }
+
+ if (lib_arch.endianness != arch_array[running_arch_index].endianness) {
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: endianness mismatch)");
+ return NULL;
+ }
+
+ // ELF file class/capacity : 0 - invalid, 1 - 32bit, 2 - 64bit
+ if (lib_arch.elf_class > 2 || lib_arch.elf_class < 1) {
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: invalid ELF file class)");
+ return NULL;
+ }
+
+ if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1,
+ " (Possible cause: architecture word width mismatch, can't load %d-bit .so on a %d-bit platform)",
+ (int) lib_arch.elf_class * 32, arch_array[running_arch_index].elf_class * 32);
+ return NULL;
}
return NULL;
@@ -5122,6 +5222,10 @@
jdk_misc_signal_init();
}
+ if (AdjustStackSizeForTLS) {
+ get_minstack_init();
+ }
+
// Check and sets minimum stack sizes against command line options
if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
return JNI_ERR;
--- a/src/hotspot/os/linux/perfMemory_linux.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/linux/perfMemory_linux.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1107,7 +1107,7 @@
if ((statbuf.st_size == 0) ||
((size_t)statbuf.st_size % os::vm_page_size() != 0)) {
- THROW_MSG_0(vmSymbols::java_lang_Exception(),
+ THROW_MSG_0(vmSymbols::java_io_IOException(),
"Invalid PerfMemory size");
}
--- a/src/hotspot/os/posix/vmError_posix.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/posix/vmError_posix.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -132,8 +132,9 @@
// Needed because asserts may happen in error handling too.
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return;
+ }
}
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
--- a/src/hotspot/os/solaris/attachListener_solaris.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/solaris/attachListener_solaris.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,17 +75,7 @@
// door descriptor returned by door_create
static int _door_descriptor;
- static void set_door_path(char* path) {
- if (path == NULL) {
- _has_door_path = false;
- } else {
- strncpy(_door_path, path, PATH_MAX);
- _door_path[PATH_MAX] = '\0'; // ensure it's nul terminated
- _has_door_path = true;
- }
- }
-
- static void set_door_descriptor(int dd) { _door_descriptor = dd; }
+ static bool _atexit_registered;
// mutex to protect operation list
static mutex_t _mutex;
@@ -121,6 +111,19 @@
ATTACH_ERROR_DENIED = 104
};
+ static void set_door_path(char* path) {
+ if (path == NULL) {
+ _door_path[0] = '\0';
+ _has_door_path = false;
+ } else {
+ strncpy(_door_path, path, PATH_MAX);
+ _door_path[PATH_MAX] = '\0'; // ensure it's nul terminated
+ _has_door_path = true;
+ }
+ }
+
+ static void set_door_descriptor(int dd) { _door_descriptor = dd; }
+
// initialize the listener
static int init();
@@ -169,6 +172,7 @@
char SolarisAttachListener::_door_path[PATH_MAX+1];
volatile bool SolarisAttachListener::_has_door_path;
int SolarisAttachListener::_door_descriptor = -1;
+bool SolarisAttachListener::_atexit_registered = false;
mutex_t SolarisAttachListener::_mutex;
sema_t SolarisAttachListener::_wakeup;
SolarisAttachOperation* SolarisAttachListener::_head = NULL;
@@ -364,18 +368,16 @@
// atexit hook to detach the door and remove the file
extern "C" {
static void listener_cleanup() {
- static int cleanup_done;
- if (!cleanup_done) {
- cleanup_done = 1;
- int dd = SolarisAttachListener::door_descriptor();
- if (dd >= 0) {
- ::close(dd);
- }
- if (SolarisAttachListener::has_door_path()) {
- char* path = SolarisAttachListener::door_path();
- ::fdetach(path);
- ::unlink(path);
- }
+ int dd = SolarisAttachListener::door_descriptor();
+ if (dd >= 0) {
+ SolarisAttachListener::set_door_descriptor(-1);
+ ::close(dd);
+ }
+ if (SolarisAttachListener::has_door_path()) {
+ char* path = SolarisAttachListener::door_path();
+ ::fdetach(path);
+ ::unlink(path);
+ SolarisAttachListener::set_door_path(NULL);
}
}
}
@@ -387,7 +389,10 @@
int fd, res;
// register exit function
- ::atexit(listener_cleanup);
+ if (!_atexit_registered) {
+ _atexit_registered = true;
+ ::atexit(listener_cleanup);
+ }
// create the door descriptor
int dd = ::door_create(enqueue_proc, NULL, 0);
@@ -643,6 +648,26 @@
}
}
+bool AttachListener::check_socket_file() {
+ int ret;
+ struct stat64 st;
+ ret = stat64(SolarisAttachListener::door_path(), &st);
+ if (ret == -1) { // need to restart attach listener.
+ log_debug(attach)("Door file %s does not exist - Restart Attach Listener",
+ SolarisAttachListener::door_path());
+
+ listener_cleanup();
+
+ // wait to terminate current attach listener instance...
+ while (AttachListener::transit_state(AL_INITIALIZING,
+ AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+ os::naked_yield();
+ }
+ return is_init_trigger();
+ }
+ return false;
+}
+
// If the file .attach_pid<pid> exists in the working directory
// or /tmp then this is the trigger to start the attach mechanism
bool AttachListener::is_init_trigger() {
--- a/src/hotspot/os/solaris/os_solaris.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/solaris/os_solaris.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1520,6 +1520,13 @@
}
}
+static void change_endianness(Elf32_Half& val) {
+ unsigned char *ptr = (unsigned char *)&val;
+ unsigned char swp = ptr[0];
+ ptr[0] = ptr[1];
+ ptr[1] = swp;
+}
+
// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
@@ -1570,6 +1577,14 @@
return NULL;
}
+ if (elf_head.e_ident[EI_DATA] != LITTLE_ENDIAN_ONLY(ELFDATA2LSB) BIG_ENDIAN_ONLY(ELFDATA2MSB)) {
+ // handle invalid/out of range endianness values
+ if (elf_head.e_ident[EI_DATA] == 0 || elf_head.e_ident[EI_DATA] > 2) {
+ return NULL;
+ }
+ change_endianness(elf_head.e_machine);
+ }
+
typedef struct {
Elf32_Half code; // Actual value as defined in elf.h
Elf32_Half compat_class; // Compatibility of archs at VM's sense
@@ -1588,7 +1603,10 @@
{EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
- {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"}
+ {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
+ // we only support 64 bit z architecture
+ {EM_S390, EM_S390, ELFCLASS64, ELFDATA2MSB, (char*)"IBM System/390"},
+ {EM_AARCH64, EM_AARCH64, ELFCLASS64, ELFDATA2LSB, (char*)"AARCH64"}
};
#if (defined IA32)
@@ -1612,7 +1630,7 @@
IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM
#endif
- // Identify compatability class for VM's architecture and library's architecture
+ // Identify compatibility class for VM's architecture and library's architecture
// Obtain string descriptions for architectures
arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
@@ -1636,29 +1654,37 @@
return NULL;
}
+ if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
+ if (lib_arch.name != NULL) {
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1,
+ " (Possible cause: can't load %s .so on a %s platform)",
+ lib_arch.name, arch_array[running_arch_index].name);
+ } else {
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1,
+ " (Possible cause: can't load this .so (machine code=0x%x) on a %s platform)",
+ lib_arch.code, arch_array[running_arch_index].name);
+ }
+ return NULL;
+ }
+
if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
return NULL;
}
+ // ELF file class/capacity : 0 - invalid, 1 - 32bit, 2 - 64bit
+ if (lib_arch.elf_class > 2 || lib_arch.elf_class < 1) {
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: invalid ELF file class)");
+ return NULL;
+ }
+
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
- ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
+ ::snprintf(diag_msg_buf, diag_msg_max_length-1,
+ " (Possible cause: architecture word width mismatch, can't load %d-bit .so on a %d-bit platform)",
+ (int) lib_arch.elf_class * 32, arch_array[running_arch_index].elf_class * 32);
return NULL;
}
- if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
- if (lib_arch.name!=NULL) {
- ::snprintf(diag_msg_buf, diag_msg_max_length-1,
- " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
- lib_arch.name, arch_array[running_arch_index].name);
- } else {
- ::snprintf(diag_msg_buf, diag_msg_max_length-1,
- " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
- lib_arch.code,
- arch_array[running_arch_index].name);
- }
- }
-
return NULL;
}
--- a/src/hotspot/os/solaris/perfMemory_solaris.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/solaris/perfMemory_solaris.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1055,7 +1055,7 @@
if ((statbuf.st_size == 0) ||
((size_t)statbuf.st_size % os::vm_page_size() != 0)) {
- THROW_MSG_0(vmSymbols::java_lang_Exception(),
+ THROW_MSG_0(vmSymbols::java_io_IOException(),
"Invalid PerfMemory size");
}
--- a/src/hotspot/os/windows/attachListener_windows.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/windows/attachListener_windows.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -272,23 +272,13 @@
// open the pipe to the client
HANDLE Win32AttachOperation::open_pipe() {
- HANDLE hPipe;
-
- hPipe = ::CreateFile( pipe(), // pipe name
+ HANDLE hPipe = ::CreateFile( pipe(), // pipe name
GENERIC_WRITE, // write only
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
-
- if (hPipe != INVALID_HANDLE_VALUE) {
- // shouldn't happen as there is a pipe created per operation
- if (::GetLastError() == ERROR_PIPE_BUSY) {
- ::CloseHandle(hPipe);
- return INVALID_HANDLE_VALUE;
- }
- }
return hPipe;
}
@@ -307,8 +297,7 @@
}
buf += nwrote;
len -= nwrote;
- }
- while (len > 0);
+ } while (len > 0);
return TRUE;
}
@@ -326,6 +315,7 @@
// java_suspend_self() via check_and_wait_while_suspended()
HANDLE hPipe = open_pipe();
+ int lastError = (int)::GetLastError();
if (hPipe != INVALID_HANDLE_VALUE) {
BOOL fSuccess;
@@ -337,6 +327,7 @@
if (fSuccess) {
fSuccess = write_pipe(hPipe, (char*)result_stream->base(), (int)(result_stream->size()));
}
+ lastError = (int)::GetLastError();
// Need to flush buffers
FlushFileBuffers(hPipe);
@@ -345,10 +336,10 @@
if (fSuccess) {
log_debug(attach)("wrote result of attach operation %s to pipe %s", name(), pipe());
} else {
- log_error(attach)("failure writing result of operation %s to pipe %s", name(), pipe());
+ log_error(attach)("failure (%d) writing result of operation %s to pipe %s", lastError, name(), pipe());
}
} else {
- log_error(attach)("could not open pipe %s to send result of operation %s", pipe(), name());
+ log_error(attach)("could not open (%d) pipe %s to send result of operation %s", lastError, pipe(), name());
}
DWORD res = ::WaitForSingleObject(Win32AttachListener::mutex(), INFINITE);
@@ -392,6 +383,12 @@
return Win32AttachListener::init();
}
+// This function is used for Un*x OSes only.
+// We need not to implement it for Windows.
+bool AttachListener::check_socket_file() {
+ return false;
+}
+
bool AttachListener::init_at_startup() {
return true;
}
--- a/src/hotspot/os/windows/perfMemory_windows.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os/windows/perfMemory_windows.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1561,7 +1561,7 @@
warning("unexpected file size: size = " SIZE_FORMAT "\n",
statbuf.st_size);
}
- THROW_MSG_0(vmSymbols::java_lang_Exception(),
+ THROW_MSG_0(vmSymbols::java_io_IOException(),
"Invalid PerfMemory size");
}
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -279,8 +279,9 @@
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return 1;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return 1;
+ }
}
#endif
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -301,8 +301,9 @@
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return 1;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return 1;
+ }
}
#endif
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -271,8 +271,9 @@
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return 1;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return 1;
+ }
}
#endif
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -270,8 +270,9 @@
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return 1;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return 1;
+ }
}
#endif
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -514,8 +514,9 @@
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return 1;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return 1;
+ }
}
#endif
--- a/src/hotspot/os_cpu/linux_x86/orderAccess_linux_x86.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_x86/orderAccess_linux_x86.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -57,7 +57,13 @@
inline void OrderAccess::cross_modify_fence() {
int idx = 0;
+#ifdef AMD64
__asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory");
+#else
+ // On some x86 systems EBX is a reserved register that cannot be
+ // clobbered, so we must protect it around the CPUID.
+ __asm__ volatile ("xchg %%esi, %%ebx; cpuid; xchg %%esi, %%ebx " : "+a" (idx) : : "esi", "ecx", "edx", "memory");
+#endif
}
template<>
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -303,8 +303,9 @@
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
- handle_assert_poison_fault(ucVoid, info->si_addr);
- return 1;
+ if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
+ return 1;
+ }
}
#endif
--- a/src/hotspot/share/adlc/formssel.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/adlc/formssel.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1513,7 +1513,7 @@
MatchNode *mnode =
strcmp(_matrule->_opType, "Set") ? _matrule : _matrule->_rChild;
- mnode->count_instr_names(names);
+ if (mnode != NULL) mnode->count_instr_names(names);
uint first = 1;
// Start with the predicate supplied in the .ad file.
@@ -1726,26 +1726,25 @@
const char *description = NULL;
const char *value = NULL;
// Check if user provided any opcode definitions
- if( this != NULL ) {
- // Update 'value' if user provided a definition in the instruction
- switch (desired_opcode) {
- case PRIMARY:
- description = "primary()";
- if( _primary != NULL) { value = _primary; }
- break;
- case SECONDARY:
- description = "secondary()";
- if( _secondary != NULL ) { value = _secondary; }
- break;
- case TERTIARY:
- description = "tertiary()";
- if( _tertiary != NULL ) { value = _tertiary; }
- break;
- default:
- assert( false, "ShouldNotReachHere();");
- break;
- }
+ // Update 'value' if user provided a definition in the instruction
+ switch (desired_opcode) {
+ case PRIMARY:
+ description = "primary()";
+ if( _primary != NULL) { value = _primary; }
+ break;
+ case SECONDARY:
+ description = "secondary()";
+ if( _secondary != NULL ) { value = _secondary; }
+ break;
+ case TERTIARY:
+ description = "tertiary()";
+ if( _tertiary != NULL ) { value = _tertiary; }
+ break;
+ default:
+ assert( false, "ShouldNotReachHere();");
+ break;
}
+
if (value != NULL) {
fprintf(fp, "(%s /*%s*/)", value, description);
}
@@ -3413,7 +3412,6 @@
// Count occurrences of operands names in the leaves of the instruction
// match rule.
void MatchNode::count_instr_names( Dict &names ) {
- if( this == NULL ) return;
if( _lChild ) _lChild->count_instr_names(names);
if( _rChild ) _rChild->count_instr_names(names);
if( !_lChild && !_rChild ) {
@@ -3513,7 +3511,7 @@
"GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
"GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
#if INCLUDE_ZGC
- "LoadBarrierSlowReg", "ZGetAndSetP", "ZCompareAndSwapP", "ZCompareAndExchangeP", "ZWeakCompareAndSwapP",
+ "ZGetAndSetP", "ZCompareAndSwapP", "ZCompareAndExchangeP", "ZWeakCompareAndSwapP",
#endif
"ClearArray"
};
--- a/src/hotspot/share/adlc/output_c.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/adlc/output_c.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2377,7 +2377,7 @@
_processing_noninput = false;
// A replacement variable, originally '$'
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
- if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
+ if ((_inst._opcode == NULL) || !_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
// Missing opcode
_AD.syntax_err( _inst._linenum,
"Missing $%s opcode definition in %s, used by encoding %s\n",
@@ -2433,7 +2433,7 @@
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
// else check if "primary", "secondary", "tertiary"
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
- if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
+ if ((_inst._opcode == NULL) || !_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
// Missing opcode
_AD.syntax_err( _inst._linenum,
"Missing $%s opcode definition in %s\n",
--- a/src/hotspot/share/c1/c1_Runtime1.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -294,6 +294,12 @@
if (entry == entry_for((StubID)id)) return name_for((StubID)id);
}
+ BarrierSetC1* bsc1 = BarrierSet::barrier_set()->barrier_set_c1();
+ const char* name = bsc1->rtcall_name_for_address(entry);
+ if (name != NULL) {
+ return name;
+ }
+
#define FUNCTION_CASE(a, f) \
if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f)) return #f
--- a/src/hotspot/share/ci/ciEnv.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/ci/ciEnv.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -98,7 +98,7 @@
// ------------------------------------------------------------------
// ciEnv::ciEnv
-ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter)
+ciEnv::ciEnv(CompileTask* task)
: _ciEnv_arena(mtCompiler) {
VM_ENTRY_MARK;
@@ -118,7 +118,6 @@
assert(!firstEnv, "not initialized properly");
#endif /* !PRODUCT */
- _system_dictionary_modification_counter = system_dictionary_modification_counter;
_num_inlined_bytecodes = 0;
assert(task == NULL || thread->task() == task, "sanity");
if (task != NULL) {
@@ -183,7 +182,6 @@
firstEnv = false;
#endif /* !PRODUCT */
- _system_dictionary_modification_counter = 0;
_num_inlined_bytecodes = 0;
_task = NULL;
_log = NULL;
@@ -919,17 +917,6 @@
return JavaThread::current()->thread_state() == _thread_in_vm;
}
-bool ciEnv::system_dictionary_modification_counter_changed_locked() {
- assert_locked_or_safepoint(Compile_lock);
- return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications();
-}
-
-bool ciEnv::system_dictionary_modification_counter_changed() {
- VM_ENTRY_MARK;
- MutexLocker ml(Compile_lock, THREAD); // lock with safepoint check
- return system_dictionary_modification_counter_changed_locked();
-}
-
// ------------------------------------------------------------------
// ciEnv::validate_compile_task_dependencies
//
@@ -938,8 +925,7 @@
void ciEnv::validate_compile_task_dependencies(ciMethod* target) {
if (failing()) return; // no need for further checks
- bool counter_changed = system_dictionary_modification_counter_changed_locked();
- Dependencies::DepType result = dependencies()->validate_dependencies(_task, counter_changed);
+ Dependencies::DepType result = dependencies()->validate_dependencies(_task);
if (result != Dependencies::end_marker) {
if (result == Dependencies::call_site_target_value) {
_inc_decompile_count_on_failure = false;
--- a/src/hotspot/share/ci/ciEnv.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/ci/ciEnv.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -51,7 +51,6 @@
private:
Arena* _arena; // Alias for _ciEnv_arena except in init_shared_objects()
Arena _ciEnv_arena;
- int _system_dictionary_modification_counter;
ciObjectFactory* _factory;
OopRecorder* _oop_recorder;
DebugInformationRecorder* _debug_info;
@@ -291,9 +290,6 @@
// Helper routine for determining the validity of a compilation with
// respect to method dependencies (e.g. concurrent class loading).
void validate_compile_task_dependencies(ciMethod* target);
-
- // Call internally when Compile_lock is already held.
- bool system_dictionary_modification_counter_changed_locked();
public:
enum {
MethodCompilable,
@@ -301,7 +297,7 @@
MethodCompilable_never
};
- ciEnv(CompileTask* task, int system_dictionary_modification_counter);
+ ciEnv(CompileTask* task);
// Used only during initialization of the ci
ciEnv(Arena* arena);
~ciEnv();
@@ -456,9 +452,6 @@
CompileLog* log() { return _log; }
void set_log(CompileLog* log) { _log = log; }
- // Check for changes to the system dictionary during compilation
- bool system_dictionary_modification_counter_changed();
-
void record_failure(const char* reason); // Record failure and report later
void report_failure(const char* reason); // Report failure immediately
void record_method_not_compilable(const char* reason, bool all_tiers = true);
--- a/src/hotspot/share/classfile/classLoaderData.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -266,6 +266,19 @@
}
#endif // PRODUCT
+void ClassLoaderData::clear_claim(int claim) {
+ for (;;) {
+ int old_claim = Atomic::load(&_claim);
+ if ((old_claim & claim) == 0) {
+ return;
+ }
+ int new_claim = old_claim & ~claim;
+ if (Atomic::cmpxchg(new_claim, &_claim, old_claim) == old_claim) {
+ return;
+ }
+ }
+}
+
bool ClassLoaderData::try_claim(int claim) {
for (;;) {
int old_claim = Atomic::load(&_claim);
--- a/src/hotspot/share/classfile/classLoaderData.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/classLoaderData.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -206,16 +206,17 @@
// The "claim" is typically used to check if oops_do needs to be applied on
// the CLD or not. Most GCs only perform strong marking during the marking phase.
- enum {
- _claim_none = 0,
- _claim_finalizable = 2,
- _claim_strong = 3
+ enum Claim {
+ _claim_none = 0,
+ _claim_finalizable = 2,
+ _claim_strong = 3,
+ _claim_other = 4
};
void clear_claim() { _claim = 0; }
+ void clear_claim(int claim);
bool claimed() const { return _claim != 0; }
+ bool claimed(int claim) const { return (_claim & claim) == claim; }
bool try_claim(int claim);
- int get_claim() const { return _claim; }
- void set_claim(int claim) { _claim = claim; }
// Computes if the CLD is alive or not. This is safe to call in concurrent
// contexts.
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -64,6 +64,11 @@
}
}
+void ClassLoaderDataGraph::clear_claimed_marks(int claim) {
+ for (ClassLoaderData* cld = OrderAccess::load_acquire(&_head); cld != NULL; cld = cld->next()) {
+ cld->clear_claim(claim);
+ }
+}
// Class iterator used by the compiler. It gets some number of classes at
// a safepoint to decay invocation counters on the methods.
class ClassLoaderDataGraphKlassIteratorStatic {
@@ -471,7 +476,7 @@
// The CLDs in [_head, _saved_head] were all added during last call to remember_new_clds(true);
ClassLoaderData* curr = _head;
while (curr != _saved_head) {
- if (!curr->claimed()) {
+ if (!curr->claimed(ClassLoaderData::_claim_strong)) {
array->push(curr);
LogTarget(Debug, class, loader, data) lt;
if (lt.is_enabled()) {
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -68,6 +68,7 @@
static void clean_module_and_package_info();
static void purge();
static void clear_claimed_marks();
+ static void clear_claimed_marks(int claim);
// Iteration through CLDG inside a safepoint; GC support
static void cld_do(CLDClosure* cl);
static void cld_unloading_do(CLDClosure* cl);
--- a/src/hotspot/share/classfile/stringTable.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/stringTable.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -342,7 +342,7 @@
if (found_string != NULL) {
return found_string;
}
- return do_intern(string_or_null_h, name, len, hash, CHECK_NULL);
+ return do_intern(string_or_null_h, name, len, hash, THREAD);
}
oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
--- a/src/hotspot/share/classfile/systemDictionary.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -98,7 +98,6 @@
SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL;
-int SystemDictionary::_number_of_modifications = 0;
oop SystemDictionary::_system_loader_lock_obj = NULL;
InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
@@ -115,6 +114,7 @@
const int defaultProtectionDomainCacheSize = 1009;
+OopStorage* SystemDictionary::_vm_global_oop_storage = NULL;
OopStorage* SystemDictionary::_vm_weak_oop_storage = NULL;
@@ -1039,11 +1039,7 @@
// Add to class hierarchy, initialize vtables, and do possible
// deoptimizations.
add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
-
// But, do not add to dictionary.
-
- // compiled code dependencies need to be validated anyway
- notice_modification();
}
// Rewrite and patch constant pool here.
@@ -1849,7 +1845,7 @@
return unloading_occurred;
}
-void SystemDictionary::oops_do(OopClosure* f) {
+void SystemDictionary::oops_do(OopClosure* f, bool include_handles) {
f->do_oop(&_java_system_loader);
f->do_oop(&_java_platform_loader);
f->do_oop(&_system_loader_lock_obj);
@@ -1857,6 +1853,10 @@
// Visit extra methods
invoke_method_table()->oops_do(f);
+
+ if (include_handles) {
+ vm_global_oop_storage()->oops_do(f);
+ }
}
// CDS: scan and relocate all classes referenced by _well_known_klasses[].
@@ -1880,7 +1880,6 @@
void SystemDictionary::initialize(TRAPS) {
// Allocate arrays
_placeholders = new PlaceholderTable(_placeholder_table_size);
- _number_of_modifications = 0;
_loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
_resolution_errors = new ResolutionErrorTable(_resolution_error_size);
_invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
@@ -2164,8 +2163,6 @@
InstanceKlass* sd_check = find_class(d_hash, name, dictionary);
if (sd_check == NULL) {
dictionary->add_klass(d_hash, name, k);
-
- notice_modification();
}
#ifdef ASSERT
sd_check = find_class(d_hash, name, dictionary);
@@ -2901,12 +2898,22 @@
}
void SystemDictionary::initialize_oop_storage() {
+ _vm_global_oop_storage =
+ new OopStorage("VM Global Oop Handles",
+ VMGlobalAlloc_lock,
+ VMGlobalActive_lock);
+
_vm_weak_oop_storage =
new OopStorage("VM Weak Oop Handles",
VMWeakAlloc_lock,
VMWeakActive_lock);
}
+OopStorage* SystemDictionary::vm_global_oop_storage() {
+ assert(_vm_global_oop_storage != NULL, "Uninitialized");
+ return _vm_global_oop_storage;
+}
+
OopStorage* SystemDictionary::vm_weak_oop_storage() {
assert(_vm_weak_oop_storage != NULL, "Uninitialized");
return _vm_weak_oop_storage;
--- a/src/hotspot/share/classfile/systemDictionary.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/systemDictionary.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -348,7 +348,9 @@
static bool do_unloading(GCTimer* gc_timer);
// Applies "f->do_oop" to all root oops in the system dictionary.
- static void oops_do(OopClosure* f);
+ // If include_handles is true (the default), then the handles in the
+ // storage object returned by vm_global_oop_storage() are included.
+ static void oops_do(OopClosure* f, bool include_handles = true);
// System loader lock
static oop system_loader_lock() { return _system_loader_lock_obj; }
@@ -362,13 +364,6 @@
static void print_on(outputStream* st);
static void dump(outputStream* st, bool verbose);
- // Monotonically increasing counter which grows as classes are
- // loaded or modifications such as hot-swapping or setting/removing
- // of breakpoints are performed
- static inline int number_of_modifications() { assert_locked_or_safepoint(Compile_lock); return _number_of_modifications; }
- // Needed by evolution and breakpoint code
- static inline void notice_modification() { assert_locked_or_safepoint(Compile_lock); ++_number_of_modifications; }
-
// Verification
static void verify();
@@ -555,11 +550,6 @@
// Hashtable holding placeholders for classes being loaded.
static PlaceholderTable* _placeholders;
- // Monotonically increasing counter which grows with
- // loading classes as well as hot-swapping and breakpoint setting
- // and removal.
- static int _number_of_modifications;
-
// Lock object for system class loader
static oop _system_loader_lock_obj;
@@ -575,7 +565,8 @@
// ProtectionDomain cache
static ProtectionDomainCacheTable* _pd_cache_table;
- // VM weak OopStorage object.
+ // VM OopStorage objects.
+ static OopStorage* _vm_global_oop_storage;
static OopStorage* _vm_weak_oop_storage;
protected:
@@ -633,6 +624,7 @@
}
static void initialize_oop_storage();
+ static OopStorage* vm_global_oop_storage();
static OopStorage* vm_weak_oop_storage();
protected:
--- a/src/hotspot/share/classfile/vmSymbols.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/classfile/vmSymbols.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1088,6 +1088,7 @@
\
/* support for Unsafe */ \
do_class(jdk_internal_misc_Unsafe, "jdk/internal/misc/Unsafe") \
+ do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
\
do_intrinsic(_allocateInstance, jdk_internal_misc_Unsafe, allocateInstance_name, allocateInstance_signature, F_RN) \
do_name( allocateInstance_name, "allocateInstance") \
--- a/src/hotspot/share/code/codeCache.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/code/codeCache.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -771,9 +771,10 @@
uint8_t CodeCache::_unloading_cycle = 1;
void CodeCache::increment_unloading_cycle() {
- if (_unloading_cycle == 1) {
- _unloading_cycle = 2;
- } else {
+ // 2-bit value (see IsUnloadingState in nmethod.cpp for details)
+ // 0 is reserved for new methods.
+ _unloading_cycle = (_unloading_cycle + 1) % 4;
+ if (_unloading_cycle == 0) {
_unloading_cycle = 1;
}
}
--- a/src/hotspot/share/code/dependencies.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/code/dependencies.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -627,32 +627,10 @@
guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, "invalid dependency type: %d", (int) dept);
}
-Dependencies::DepType Dependencies::validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail) {
- // First, check non-klass dependencies as we might return early and
- // not check klass dependencies if the system dictionary
- // modification counter hasn't changed (see below).
- for (Dependencies::DepStream deps(this); deps.next(); ) {
- if (deps.is_klass_type()) continue; // skip klass dependencies
- Klass* witness = deps.check_dependency();
- if (witness != NULL) {
- return deps.type();
- }
- }
-
- // Klass dependencies must be checked when the system dictionary
- // changes. If logging is enabled all violated dependences will be
- // recorded in the log. In debug mode check dependencies even if
- // the system dictionary hasn't changed to verify that no invalid
- // dependencies were inserted. Any violated dependences in this
- // case are dumped to the tty.
- if (!counter_changed && !trueInDebug) {
- return end_marker;
- }
-
+Dependencies::DepType Dependencies::validate_dependencies(CompileTask* task, char** failure_detail) {
int klass_violations = 0;
DepType result = end_marker;
for (Dependencies::DepStream deps(this); deps.next(); ) {
- if (!deps.is_klass_type()) continue; // skip non-klass dependencies
Klass* witness = deps.check_dependency();
if (witness != NULL) {
if (klass_violations == 0) {
@@ -667,12 +645,7 @@
}
}
klass_violations++;
- if (!counter_changed) {
- // Dependence failed but counter didn't change. Log a message
- // describing what failed and allow the assert at the end to
- // trigger.
- deps.print_dependency(witness);
- } else if (xtty == NULL) {
+ if (xtty == NULL) {
// If we're not logging then a single violation is sufficient,
// otherwise we want to log all the dependences which were
// violated.
@@ -681,15 +654,6 @@
}
}
- if (klass_violations != 0) {
-#ifdef ASSERT
- if (task != NULL && !counter_changed && !PrintCompilation) {
- // Print out the compile task that failed
- task->print_tty();
- }
-#endif
- assert(counter_changed, "failed dependencies, but counter didn't change");
- }
return result;
}
--- a/src/hotspot/share/code/dependencies.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/code/dependencies.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -476,7 +476,7 @@
void copy_to(nmethod* nm);
- DepType validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail = NULL);
+ DepType validate_dependencies(CompileTask* task, char** failure_detail = NULL);
void log_all_dependencies();
--- a/src/hotspot/share/code/nmethod.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/code/nmethod.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1774,10 +1774,9 @@
}
}
-void nmethod::oops_do(OopClosure* f, bool allow_zombie) {
+void nmethod::oops_do(OopClosure* f, bool allow_dead) {
// make sure the oops ready to receive visitors
- assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod");
- assert(!is_unloaded(), "should not call follow on unloaded nmethod");
+ assert(allow_dead || is_alive(), "should not call follow on dead nmethod");
// Prevent extra code cache walk for platforms that don't have immediate oops.
if (relocInfo::mustIterateImmediateOopsInCode()) {
--- a/src/hotspot/share/code/nmethod.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/code/nmethod.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -473,7 +473,7 @@
public:
void oops_do(OopClosure* f) { oops_do(f, false); }
- void oops_do(OopClosure* f, bool allow_zombie);
+ void oops_do(OopClosure* f, bool allow_dead);
bool test_set_oops_do_mark();
static void oops_do_marking_prologue();
--- a/src/hotspot/share/compiler/compileBroker.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/compiler/compileBroker.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1595,16 +1595,10 @@
// Final sanity check - the compiler object must exist
guarantee(comp != NULL, "Compiler object must exist");
- int system_dictionary_modification_counter;
- {
- MutexLocker locker(Compile_lock, thread);
- system_dictionary_modification_counter = SystemDictionary::number_of_modifications();
- }
-
{
// Must switch to native to allocate ci_env
ThreadToNativeFromVM ttn(thread);
- ciEnv ci_env(NULL, system_dictionary_modification_counter);
+ ciEnv ci_env((CompileTask*)NULL);
// Cache Jvmti state
ci_env.cache_jvmti_state();
// Cache DTrace flags
@@ -2045,12 +2039,6 @@
bool failure_reason_on_C_heap = false;
const char* retry_message = NULL;
- int system_dictionary_modification_counter;
- {
- MutexLocker locker(Compile_lock, thread);
- system_dictionary_modification_counter = SystemDictionary::number_of_modifications();
- }
-
#if INCLUDE_JVMCI
if (UseJVMCICompiler && comp != NULL && comp->is_jvmci()) {
JVMCICompiler* jvmci = (JVMCICompiler*) comp;
@@ -2064,7 +2052,7 @@
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_never;
} else {
- JVMCICompileState compile_state(task, system_dictionary_modification_counter);
+ JVMCICompileState compile_state(task);
JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
methodHandle method(thread, target_handle);
env.runtime()->compile_method(&env, jvmci, method, osr_bci);
@@ -2090,7 +2078,7 @@
NoHandleMark nhm;
ThreadToNativeFromVM ttn(thread);
- ciEnv ci_env(task, system_dictionary_modification_counter);
+ ciEnv ci_env(task);
if (should_break) {
ci_env.set_break_at_compile(true);
}
--- a/src/hotspot/share/compiler/disassembler.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/compiler/disassembler.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -315,56 +315,96 @@
}
}
-decode_env::decode_env(CodeBuffer* code, outputStream* output) {
- memset(this, 0, sizeof(*this));
- _output = output ? output : tty;
- _codeBlob = NULL;
- _codeBuffer = code;
- _helpPrinted = false;
+decode_env::decode_env(CodeBuffer* code, outputStream* output) :
+ _output(output ? output : tty),
+ _codeBuffer(code),
+ _codeBlob(NULL),
+ _nm(NULL),
+ _strings(),
+ _start(NULL),
+ _end(NULL),
+ _option_buf(),
+ _print_raw(0),
+ _cur_insn(NULL),
+ _bytes_per_line(0),
+ _pre_decode_alignment(0),
+ _post_decode_alignment(0),
+ _print_file_name(false),
+ _print_help(false),
+ _helpPrinted(false) {
+ memset(_option_buf, 0, sizeof(_option_buf));
process_options(_output);
}
-decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
- memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
- _output = output ? output : tty;
- _codeBlob = code;
- _codeBuffer = NULL;
- _helpPrinted = false;
- if (_codeBlob != NULL && _codeBlob->is_nmethod()) {
- _nm = (nmethod*) code;
- }
+decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) :
+ _output(output ? output : tty),
+ _codeBuffer(NULL),
+ _codeBlob(code),
+ _nm(_codeBlob != NULL && _codeBlob->is_nmethod() ? (nmethod*) code : NULL),
+ _strings(),
+ _start(NULL),
+ _end(NULL),
+ _option_buf(),
+ _print_raw(0),
+ _cur_insn(NULL),
+ _bytes_per_line(0),
+ _pre_decode_alignment(0),
+ _post_decode_alignment(0),
+ _print_file_name(false),
+ _print_help(false),
+ _helpPrinted(false) {
+
+ memset(_option_buf, 0, sizeof(_option_buf));
_strings.copy(c);
-
process_options(_output);
}
-decode_env::decode_env(nmethod* code, outputStream* output, CodeStrings c) {
- memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
- _output = output ? output : tty;
- _codeBlob = NULL;
- _codeBuffer = NULL;
- _nm = code;
- _start = _nm->code_begin();
- _end = _nm->code_end();
- _helpPrinted = false;
+decode_env::decode_env(nmethod* code, outputStream* output, CodeStrings c) :
+ _output(output ? output : tty),
+ _codeBuffer(NULL),
+ _codeBlob(NULL),
+ _nm(code),
+ _strings(),
+ _start(_nm->code_begin()),
+ _end(_nm->code_end()),
+ _option_buf(),
+ _print_raw(0),
+ _cur_insn(NULL),
+ _bytes_per_line(0),
+ _pre_decode_alignment(0),
+ _post_decode_alignment(0),
+ _print_file_name(false),
+ _print_help(false),
+ _helpPrinted(false) {
+
+ memset(_option_buf, 0, sizeof(_option_buf));
_strings.copy(c);
-
process_options(_output);
}
// Constructor for a 'decode_env' to decode a memory range [start, end)
// of unknown origin, assuming it contains code.
-decode_env::decode_env(address start, address end, outputStream* output) {
+decode_env::decode_env(address start, address end, outputStream* output) :
+ _output(output ? output : tty),
+ _codeBuffer(NULL),
+ _codeBlob(NULL),
+ _nm(NULL),
+ _strings(),
+ _start(start),
+ _end(end),
+ _option_buf(),
+ _print_raw(0),
+ _cur_insn(NULL),
+ _bytes_per_line(0),
+ _pre_decode_alignment(0),
+ _post_decode_alignment(0),
+ _print_file_name(false),
+ _print_help(false),
+ _helpPrinted(false) {
+
assert(start < end, "Range must have a positive size, [" PTR_FORMAT ".." PTR_FORMAT ").", p2i(start), p2i(end));
- memset(this, 0, sizeof(*this));
- _output = output ? output : tty;
- _codeBlob = NULL;
- _codeBuffer = NULL;
- _start = start;
- _end = end;
- _helpPrinted = false;
-
+ memset(_option_buf, 0, sizeof(_option_buf));
process_options(_output);
}
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -62,7 +62,7 @@
}
size_t used_in_bytes() {
- return _space->used_stable();
+ return _space->used();
}
};
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -372,8 +372,6 @@
)
}
_dictionary->set_par_lock(&_parDictionaryAllocLock);
-
- _used_stable = 0;
}
// Like CompactibleSpace forward() but always calls cross_threshold() to
@@ -579,14 +577,6 @@
return capacity() - free();
}
-size_t CompactibleFreeListSpace::used_stable() const {
- return _used_stable;
-}
-
-void CompactibleFreeListSpace::recalculate_used_stable() {
- _used_stable = used();
-}
-
size_t CompactibleFreeListSpace::free() const {
// "MT-safe, but not MT-precise"(TM), if you will: i.e.
// if you do this while the structures are in flux you
@@ -1384,9 +1374,6 @@
debug_only(fc->mangleAllocated(size));
}
- // After allocation, recalculate used space and update used_stable
- recalculate_used_stable();
-
return res;
}
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -192,9 +192,6 @@
// Used to keep track of limit of sweep for the space
HeapWord* _sweep_limit;
- // Stable value of used().
- size_t _used_stable;
-
// Used to make the young collector update the mod union table
MemRegionClosure* _preconsumptionDirtyCardClosure;
@@ -415,17 +412,6 @@
// which overestimates the region by returning the entire
// committed region (this is safe, but inefficient).
- // Returns monotonically increasing stable used space bytes for CMS.
- // This is required for jstat and other memory monitoring tools
- // that might otherwise see inconsistent used space values during a garbage
- // collection, promotion or allocation into compactibleFreeListSpace.
- // The value returned by this function might be smaller than the
- // actual value.
- size_t used_stable() const;
- // Recalculate and cache the current stable used() value. Only to be called
- // in places where we can be sure that the result is stable.
- void recalculate_used_stable();
-
// Returns a subregion of the space containing all the objects in
// the space.
MemRegion used_region() const {
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -692,10 +692,6 @@
return _cmsSpace->max_alloc_in_words() * HeapWordSize;
}
-size_t ConcurrentMarkSweepGeneration::used_stable() const {
- return cmsSpace()->used_stable();
-}
-
size_t ConcurrentMarkSweepGeneration::max_available() const {
return free() + _virtual_space.uncommitted_size();
}
@@ -1527,8 +1523,6 @@
FreelistLocker z(this);
MetaspaceGC::compute_new_size();
_cmsGen->compute_new_size_free_list();
- // recalculate CMS used space after CMS collection
- _cmsGen->cmsSpace()->recalculate_used_stable();
}
// A work method used by the foreground collector to do
@@ -2057,7 +2051,6 @@
_capacity_at_prologue = capacity();
_used_at_prologue = used();
- _cmsSpace->recalculate_used_stable();
// We enable promotion tracking so that card-scanning can recognize
// which objects have been promoted during this GC and skip them.
@@ -2130,7 +2123,6 @@
_eden_chunk_index = 0;
size_t cms_used = _cmsGen->cmsSpace()->used();
- _cmsGen->cmsSpace()->recalculate_used_stable();
// update performance counters - this uses a special version of
// update_counters() that allows the utilization to be passed as a
@@ -2824,8 +2816,6 @@
rp->enable_discovery();
_collectorState = Marking;
}
-
- _cmsGen->cmsSpace()->recalculate_used_stable();
}
void CMSCollector::checkpointRootsInitialWork() {
@@ -4187,7 +4177,6 @@
MutexLocker y(bitMapLock(),
Mutex::_no_safepoint_check_flag);
checkpointRootsFinalWork();
- _cmsGen->cmsSpace()->recalculate_used_stable();
}
verify_work_stacks_empty();
verify_overflow_empty();
@@ -5347,14 +5336,9 @@
// further below.
{
CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock());
-
// Update heap occupancy information which is used as
// input to soft ref clearing policy at the next gc.
Universe::update_heap_info_at_gc();
-
- // recalculate CMS used space after CMS collection
- _cmsGen->cmsSpace()->recalculate_used_stable();
-
_collectorState = Resizing;
}
}
@@ -5443,7 +5427,6 @@
// Gather statistics on the young generation collection.
collector()->stats().record_gc0_end(used());
}
- _cmsSpace->recalculate_used_stable();
}
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* old_gen) {
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1112,7 +1112,6 @@
double occupancy() const { return ((double)used())/((double)capacity()); }
size_t contiguous_available() const;
size_t unsafe_max_alloc_nogc() const;
- size_t used_stable() const;
// over-rides
MemRegion used_region_at_save_marks() const;
--- a/src/hotspot/share/gc/cms/gSpaceCounters.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/cms/gSpaceCounters.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -59,7 +59,7 @@
}
inline void update_used() {
- _used->set_value(_gen->used_stable());
+ _used->set_value(_gen->used());
}
// special version of update_used() to allow the used value to be
@@ -103,7 +103,7 @@
GenerationUsedHelper(Generation* g) : _gen(g) { }
inline jlong take_sample() {
- return _gen->used_stable();
+ return _gen->used();
}
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1CardTableEntryClosure.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1CARDTABLEENTRYCLOSURE_HPP
+#define SHARE_GC_G1_G1CARDTABLEENTRYCLOSURE_HPP
+
+#include "gc/shared/cardTable.hpp"
+#include "memory/allocation.hpp"
+
+// A closure class for processing card table entries. Note that we don't
+// require these closure objects to be stack-allocated.
+class G1CardTableEntryClosure: public CHeapObj<mtGC> {
+public:
+ typedef CardTable::CardValue CardValue;
+
+ // Process the card whose card table entry is "card_ptr". If returns
+ // "false", terminate the iteration early.
+ virtual bool do_card_ptr(CardValue* card_ptr, uint worker_id) = 0;
+};
+
+#endif // SHARE_GC_G1_G1CARDTABLEENTRYCLOSURE_HPP
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -31,6 +31,7 @@
#include "gc/g1/g1Allocator.inline.hpp"
#include "gc/g1/g1Arguments.hpp"
#include "gc/g1/g1BarrierSet.hpp"
+#include "gc/g1/g1CardTableEntryClosure.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectionSet.hpp"
#include "gc/g1/g1CollectorState.hpp"
@@ -49,6 +50,7 @@
#include "gc/g1/g1OopClosures.inline.hpp"
#include "gc/g1/g1ParScanThreadState.inline.hpp"
#include "gc/g1/g1Policy.hpp"
+#include "gc/g1/g1RedirtyCardsQueue.hpp"
#include "gc/g1/g1RegionToSpaceMapper.hpp"
#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/g1RootClosures.hpp"
@@ -1078,7 +1080,9 @@
// Discard all remembered set updates.
G1BarrierSet::dirty_card_queue_set().abandon_logs();
- assert(dirty_card_queue_set().completed_buffers_num() == 0, "DCQS should be empty");
+ assert(G1BarrierSet::dirty_card_queue_set().completed_buffers_num() == 0,
+ "DCQS should be empty");
+ redirty_cards_queue_set().verify_empty();
}
void G1CollectedHeap::verify_after_full_collection() {
@@ -1517,7 +1521,7 @@
_collection_set(this, _policy),
_hot_card_cache(NULL),
_rem_set(NULL),
- _dirty_card_queue_set(false),
+ _redirty_cards_queue_set(),
_cm(NULL),
_cm_thread(NULL),
_cr(NULL),
@@ -1687,8 +1691,8 @@
&bs->dirty_card_queue_buffer_allocator(),
true); // init_free_ids
- dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
- &bs->dirty_card_queue_buffer_allocator());
+ // Use same buffer allocator as dirty card qset, to allow merging.
+ _redirty_cards_queue_set.initialize(&bs->dirty_card_queue_buffer_allocator());
// Create the hot card cache.
_hot_card_cache = new G1HotCardCache(this);
@@ -3213,18 +3217,43 @@
class G1RedirtyLoggedCardsTask : public AbstractGangTask {
private:
- G1DirtyCardQueueSet* _queue;
+ G1RedirtyCardsQueueSet* _qset;
G1CollectedHeap* _g1h;
+ BufferNode* volatile _nodes;
+
+ void apply(G1CardTableEntryClosure* cl, BufferNode* node, uint worker_id) {
+ void** buf = BufferNode::make_buffer_from_node(node);
+ size_t limit = _qset->buffer_size();
+ for (size_t i = node->index(); i < limit; ++i) {
+ CardTable::CardValue* card_ptr = static_cast<CardTable::CardValue*>(buf[i]);
+ bool result = cl->do_card_ptr(card_ptr, worker_id);
+ assert(result, "Closure should always return true");
+ }
+ }
+
+ void par_apply(G1CardTableEntryClosure* cl, uint worker_id) {
+ BufferNode* next = Atomic::load(&_nodes);
+ while (next != NULL) {
+ BufferNode* node = next;
+ next = Atomic::cmpxchg(node->next(), &_nodes, node);
+ if (next == node) {
+ apply(cl, node, worker_id);
+ next = node->next();
+ }
+ }
+ }
+
public:
- G1RedirtyLoggedCardsTask(G1DirtyCardQueueSet* queue, G1CollectedHeap* g1h) : AbstractGangTask("Redirty Cards"),
- _queue(queue), _g1h(g1h) { }
+ G1RedirtyLoggedCardsTask(G1RedirtyCardsQueueSet* qset, G1CollectedHeap* g1h) :
+ AbstractGangTask("Redirty Cards"),
+ _qset(qset), _g1h(g1h), _nodes(qset->all_completed_buffers()) { }
virtual void work(uint worker_id) {
G1GCPhaseTimes* p = _g1h->phase_times();
G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::RedirtyCards, worker_id);
RedirtyLoggedCardTableEntryClosure cl(_g1h);
- _queue->par_apply_closure_to_all_completed_buffers(&cl);
+ par_apply(&cl, worker_id);
p->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_dirtied());
}
@@ -3233,13 +3262,12 @@
void G1CollectedHeap::redirty_logged_cards() {
double redirty_logged_cards_start = os::elapsedTime();
- G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set(), this);
- dirty_card_queue_set().reset_for_par_iteration();
+ G1RedirtyLoggedCardsTask redirty_task(&redirty_cards_queue_set(), this);
workers()->run_task(&redirty_task);
G1DirtyCardQueueSet& dcq = G1BarrierSet::dirty_card_queue_set();
- dcq.merge_bufferlists(&dirty_card_queue_set());
- assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
+ dcq.merge_bufferlists(&redirty_cards_queue_set());
+ redirty_cards_queue_set().verify_empty();
phase_times()->record_redirty_logged_cards_time_ms((os::elapsedTime() - redirty_logged_cards_start) * 1000.0);
}
@@ -3571,7 +3599,7 @@
// Should G1EvacuationFailureALot be in effect for this GC?
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
- assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
+ redirty_cards_queue_set().verify_empty();
}
class G1EvacuateRegionsBaseTask : public AbstractGangTask {
@@ -3683,7 +3711,7 @@
{
Ticks start = Ticks::now();
- rem_set()->merge_heap_roots(false /* remset_only */, G1GCPhaseTimes::MergeRS);
+ rem_set()->merge_heap_roots(true /* initial_evacuation */);
p->record_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
}
@@ -3759,7 +3787,7 @@
{
Ticks start = Ticks::now();
- rem_set()->merge_heap_roots(true /* remset_only */, G1GCPhaseTimes::OptMergeRS);
+ rem_set()->merge_heap_roots(false /* initial_evacuation */);
phase_times()->record_or_add_optional_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
}
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -31,7 +31,6 @@
#include "gc/g1/g1CollectionSet.hpp"
#include "gc/g1/g1CollectorState.hpp"
#include "gc/g1/g1ConcurrentMark.hpp"
-#include "gc/g1/g1DirtyCardQueue.hpp"
#include "gc/g1/g1EdenRegions.hpp"
#include "gc/g1/g1EvacFailure.hpp"
#include "gc/g1/g1EvacStats.hpp"
@@ -42,6 +41,7 @@
#include "gc/g1/g1HRPrinter.hpp"
#include "gc/g1/g1HeapRegionAttr.hpp"
#include "gc/g1/g1MonitoringSupport.hpp"
+#include "gc/g1/g1RedirtyCardsQueue.hpp"
#include "gc/g1/g1SurvivorRegions.hpp"
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/heapRegionManager.hpp"
@@ -73,6 +73,7 @@
class SpaceClosure;
class CompactibleSpaceClosure;
class Space;
+class G1CardTableEntryClosure;
class G1CollectionSet;
class G1Policy;
class G1HotCardCache;
@@ -353,6 +354,7 @@
assert(Thread::current()->is_VM_thread(), "current thread is not VM thread"); \
} while (0)
+#ifdef ASSERT
#define assert_used_and_recalculate_used_equal(g1h) \
do { \
size_t cur_used_bytes = g1h->used(); \
@@ -361,6 +363,9 @@
" same as recalculated used(" SIZE_FORMAT ").", \
cur_used_bytes, recal_used_bytes); \
} while (0)
+#else
+#define assert_used_and_recalculate_used_equal(g1h) do {} while(0)
+#endif
const char* young_gc_name() const;
@@ -771,7 +776,7 @@
// A set of cards that cover the objects for which the Rsets should be updated
// concurrently after the collection.
- G1DirtyCardQueueSet _dirty_card_queue_set;
+ G1RedirtyCardsQueueSet _redirty_cards_queue_set;
// After a collection pause, convert the regions in the collection set into free
// regions.
@@ -931,7 +936,9 @@
uint num_task_queues() const;
// A set of cards where updates happened during the GC
- G1DirtyCardQueueSet& dirty_card_queue_set() { return _dirty_card_queue_set; }
+ G1RedirtyCardsQueueSet& redirty_cards_queue_set() {
+ return _redirty_cards_queue_set;
+ }
// Create a G1CollectedHeap.
// Must call the initialize method afterwards.
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -23,9 +23,11 @@
*/
#include "precompiled.hpp"
+#include "gc/g1/g1CardTableEntryClosure.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1DirtyCardQueue.hpp"
#include "gc/g1/g1FreeIdSet.hpp"
+#include "gc/g1/g1RedirtyCardsQueue.hpp"
#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/g1ThreadLocalData.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
@@ -90,8 +92,7 @@
_completed_buffers_padding(0),
_free_ids(NULL),
_processed_buffers_mut(0),
- _processed_buffers_rs_thread(0),
- _cur_par_buffer_node(NULL)
+ _processed_buffers_rs_thread(0)
{
_all_active = true;
}
@@ -211,26 +212,22 @@
// Merge lists of buffers. Notify the processing threads.
// The source queue is emptied as a result. The queues
// must share the monitor.
-void G1DirtyCardQueueSet::merge_bufferlists(G1DirtyCardQueueSet *src) {
- assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
+void G1DirtyCardQueueSet::merge_bufferlists(G1RedirtyCardsQueueSet* src) {
+ assert(allocator() == src->allocator(), "precondition");
+ const G1RedirtyCardsBufferList from = src->take_all_completed_buffers();
+ if (from._head == NULL) return;
+
MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
if (_completed_buffers_tail == NULL) {
assert(_completed_buffers_head == NULL, "Well-formedness");
- _completed_buffers_head = src->_completed_buffers_head;
- _completed_buffers_tail = src->_completed_buffers_tail;
+ _completed_buffers_head = from._head;
+ _completed_buffers_tail = from._tail;
} else {
assert(_completed_buffers_head != NULL, "Well formedness");
- if (src->_completed_buffers_head != NULL) {
- _completed_buffers_tail->set_next(src->_completed_buffers_head);
- _completed_buffers_tail = src->_completed_buffers_tail;
- }
+ _completed_buffers_tail->set_next(from._head);
+ _completed_buffers_tail = from._tail;
}
- _n_completed_buffers += src->_n_completed_buffers;
-
- src->_n_completed_buffers = 0;
- src->_completed_buffers_head = NULL;
- src->_completed_buffers_tail = NULL;
- src->set_process_completed_buffers(false);
+ _n_completed_buffers += from._count;
assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
_completed_buffers_head != NULL && _completed_buffers_tail != NULL,
@@ -240,7 +237,6 @@
bool G1DirtyCardQueueSet::apply_closure_to_buffer(G1CardTableEntryClosure* cl,
BufferNode* node,
- bool consume,
uint worker_i) {
if (cl == NULL) return true;
bool result = true;
@@ -255,10 +251,8 @@
break;
}
}
- if (consume) {
- assert(i <= buffer_size(), "invariant");
- node->set_index(i);
- }
+ assert(i <= buffer_size(), "invariant");
+ node->set_index(i);
return result;
}
@@ -299,7 +293,7 @@
uint worker_i = _free_ids->claim_par_id(); // temporarily claim an id
G1RefineCardConcurrentlyClosure cl;
- bool result = apply_closure_to_buffer(&cl, node, true, worker_i);
+ bool result = apply_closure_to_buffer(&cl, node, worker_i);
_free_ids->release_par_id(worker_i); // release the id
if (result) {
@@ -328,7 +322,7 @@
if (nd == NULL) {
return false;
} else {
- if (apply_closure_to_buffer(cl, nd, true, worker_i)) {
+ if (apply_closure_to_buffer(cl, nd, worker_i)) {
assert_fully_consumed(nd, buffer_size());
// Done with fully processed buffer.
deallocate_buffer(nd);
@@ -342,21 +336,6 @@
}
}
-void G1DirtyCardQueueSet::par_apply_closure_to_all_completed_buffers(G1CardTableEntryClosure* cl) {
- BufferNode* nd = _cur_par_buffer_node;
- while (nd != NULL) {
- BufferNode* next = nd->next();
- BufferNode* actual = Atomic::cmpxchg(next, &_cur_par_buffer_node, nd);
- if (actual == nd) {
- bool b = apply_closure_to_buffer(cl, nd, false);
- guarantee(b, "Should not stop early.");
- nd = next;
- } else {
- nd = actual;
- }
- }
-}
-
void G1DirtyCardQueueSet::abandon_logs() {
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
abandon_completed_buffers();
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,26 +25,16 @@
#ifndef SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP
#define SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP
-#include "gc/shared/cardTable.hpp"
#include "gc/shared/ptrQueue.hpp"
#include "memory/allocation.hpp"
+class G1CardTableEntryClosure;
class G1DirtyCardQueueSet;
class G1FreeIdSet;
+class G1RedirtyCardsQueueSet;
class Thread;
class Monitor;
-// A closure class for processing card table entries. Note that we don't
-// require these closure objects to be stack-allocated.
-class G1CardTableEntryClosure: public CHeapObj<mtGC> {
-public:
- typedef CardTable::CardValue CardValue;
-
- // Process the card whose card table entry is "card_ptr". If returns
- // "false", terminate the iteration early.
- virtual bool do_card_ptr(CardValue* card_ptr, uint worker_i) = 0;
-};
-
// A ptrQueue whose elements are "oops", pointers to object heads.
class G1DirtyCardQueue: public PtrQueue {
protected:
@@ -95,12 +85,12 @@
// buffer_size. If all closure applications return true, then
// returns true. Stops processing after the first closure
// application that returns false, and returns false from this
- // function. If "consume" is true, the node's index is updated to
- // exclude the processed elements, e.g. up to the element for which
- // the closure returned false.
+ // function. The node's index is updated to exclude the processed
+ // elements, e.g. up to the element for which the closure returned
+ // false, or one past the last element if the closure always
+ // returned true.
bool apply_closure_to_buffer(G1CardTableEntryClosure* cl,
BufferNode* node,
- bool consume,
uint worker_i = 0);
// If there are more than stop_at completed buffers, pop one, apply
@@ -135,9 +125,6 @@
jint _processed_buffers_mut;
jint _processed_buffers_rs_thread;
- // Current buffer node used for parallel iteration.
- BufferNode* volatile _cur_par_buffer_node;
-
public:
G1DirtyCardQueueSet(bool notify_when_complete = true);
~G1DirtyCardQueueSet();
@@ -183,7 +170,7 @@
// Notify the consumer if the number of buffers crossed the threshold
void notify_if_necessary();
- void merge_bufferlists(G1DirtyCardQueueSet* src);
+ void merge_bufferlists(G1RedirtyCardsQueueSet* src);
// Apply G1RefineCardConcurrentlyClosure to completed buffers until there are stop_at
// completed buffers remaining.
@@ -193,12 +180,6 @@
// must never return false. Must only be called during GC.
bool apply_closure_during_gc(G1CardTableEntryClosure* cl, uint worker_i);
- void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; }
- // Applies the current closure to all completed buffers, non-consumptively.
- // Can be used in parallel, all callers using the iteration state initialized
- // by reset_for_par_iteration.
- void par_apply_closure_to_all_completed_buffers(G1CardTableEntryClosure* cl);
-
// If a full collection is happening, reset partial logs, and release
// completed ones: the full collection will make them all irrelevant.
void abandon_logs();
--- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,10 +26,10 @@
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorState.hpp"
#include "gc/g1/g1ConcurrentMark.inline.hpp"
-#include "gc/g1/g1DirtyCardQueue.hpp"
#include "gc/g1/g1EvacFailure.hpp"
#include "gc/g1/g1HeapVerifier.hpp"
#include "gc/g1/g1OopClosures.inline.hpp"
+#include "gc/g1/g1RedirtyCardsQueue.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/shared/preservedMarks.inline.hpp"
@@ -40,7 +40,7 @@
class UpdateLogBuffersDeferred : public BasicOopIterateClosure {
private:
G1CollectedHeap* _g1h;
- G1DirtyCardQueue* _dcq;
+ G1RedirtyCardsQueue* _rdcq;
G1CardTable* _ct;
// Remember the last enqueued card to avoid enqueuing the same card over and over;
@@ -48,8 +48,8 @@
size_t _last_enqueued_card;
public:
- UpdateLogBuffersDeferred(G1DirtyCardQueue* dcq) :
- _g1h(G1CollectedHeap::heap()), _dcq(dcq), _ct(_g1h->card_table()), _last_enqueued_card(SIZE_MAX) {}
+ UpdateLogBuffersDeferred(G1RedirtyCardsQueue* rdcq) :
+ _g1h(G1CollectedHeap::heap()), _rdcq(rdcq), _ct(_g1h->card_table()), _last_enqueued_card(SIZE_MAX) {}
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); }
@@ -67,7 +67,7 @@
}
size_t card_index = _ct->index_for(p);
if (card_index != _last_enqueued_card) {
- _dcq->enqueue(_ct->byte_for_index(card_index));
+ _rdcq->enqueue(_ct->byte_for_index(card_index));
_last_enqueued_card = card_index;
}
}
@@ -199,15 +199,15 @@
G1CollectedHeap* _g1h;
uint _worker_id;
- G1DirtyCardQueue _dcq;
+ G1RedirtyCardsQueue _rdcq;
UpdateLogBuffersDeferred _log_buffer_cl;
public:
RemoveSelfForwardPtrHRClosure(uint worker_id) :
_g1h(G1CollectedHeap::heap()),
_worker_id(worker_id),
- _dcq(&_g1h->dirty_card_queue_set()),
- _log_buffer_cl(&_dcq) {
+ _rdcq(&_g1h->redirty_cards_queue_set()),
+ _log_buffer_cl(&_rdcq) {
}
size_t remove_self_forward_ptr_by_walking_hr(HeapRegion* hr,
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -61,11 +61,12 @@
_gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms):");
_gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms):");
AOT_ONLY(_gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>(max_gc_threads, "AOT Root Scan (ms):");)
- JVMCI_ONLY(_gc_par_phases[JVMCIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMCI Root Scan (ms):");)
_gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms):");
_gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms):");
_gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms):");
+ _gc_par_phases[MergeER] = new WorkerDataArray<double>(max_gc_threads, "Eager Reclaim (ms):");
+
_gc_par_phases[MergeRS] = new WorkerDataArray<double>(max_gc_threads, "Remembered Sets (ms):");
_merge_rs_merged_sparse = new WorkerDataArray<size_t>(max_gc_threads, "Merged Sparse:");
_gc_par_phases[MergeRS]->link_thread_work_items(_merge_rs_merged_sparse, MergeRSMergedSparse);
@@ -166,6 +167,8 @@
_cur_strong_code_root_purge_time_ms = 0.0;
_cur_merge_heap_roots_time_ms = 0.0;
_cur_optional_merge_heap_roots_time_ms = 0.0;
+ _cur_prepare_merge_heap_roots_time_ms = 0.0;
+ _cur_optional_prepare_merge_heap_roots_time_ms = 0.0;
_cur_evac_fail_recalc_used = 0.0;
_cur_evac_fail_remove_self_forwards = 0.0;
_cur_string_deduplication_time_ms = 0.0;
@@ -248,9 +251,10 @@
// Make sure all slots are uninitialized since this thread did not seem to have been started
ASSERT_PHASE_UNINITIALIZED(GCWorkerEnd);
ASSERT_PHASE_UNINITIALIZED(ExtRootScan);
- ASSERT_PHASE_UNINITIALIZED(MergeHCC);
+ ASSERT_PHASE_UNINITIALIZED(MergeER);
ASSERT_PHASE_UNINITIALIZED(MergeRS);
ASSERT_PHASE_UNINITIALIZED(OptMergeRS);
+ ASSERT_PHASE_UNINITIALIZED(MergeHCC);
ASSERT_PHASE_UNINITIALIZED(MergeLB);
ASSERT_PHASE_UNINITIALIZED(ScanHR);
ASSERT_PHASE_UNINITIALIZED(CodeRoots);
@@ -413,6 +417,8 @@
const double sum_ms = _cur_optional_evac_ms + _cur_optional_merge_heap_roots_time_ms;
if (sum_ms > 0) {
info_time("Merge Optional Heap Roots", _cur_optional_merge_heap_roots_time_ms);
+
+ debug_time("Prepare Optional Merge Heap Roots", _cur_optional_prepare_merge_heap_roots_time_ms);
debug_phase(_gc_par_phases[OptMergeRS]);
info_time("Evacuate Optional Collection Set", _cur_optional_evac_ms);
@@ -427,6 +433,8 @@
double G1GCPhaseTimes::print_evacuate_initial_collection_set() const {
info_time("Merge Heap Roots", _cur_merge_heap_roots_time_ms);
+ debug_time("Prepare Merge Heap Roots", _cur_prepare_merge_heap_roots_time_ms);
+ debug_phase(_gc_par_phases[MergeER]);
debug_phase(_gc_par_phases[MergeRS]);
if (G1HotCardCache::default_use_cache()) {
debug_phase(_gc_par_phases[MergeHCC]);
@@ -554,10 +562,10 @@
"CLDGRoots",
"JVMTIRoots",
AOT_ONLY("AOTCodeRoots" COMMA)
- JVMCI_ONLY("JVMCIRoots" COMMA)
"CMRefRoots",
"WaitForStrongCLD",
"WeakCLDRoots",
+ "MergeER",
"MergeRS",
"OptMergeRS",
"MergeLB",
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -56,10 +56,10 @@
CLDGRoots,
JVMTIRoots,
AOT_ONLY(AOTCodeRoots COMMA)
- JVMCI_ONLY(JVMCIRoots COMMA)
CMRefRoots,
WaitForStrongCLD,
WeakCLDRoots,
+ MergeER,
MergeRS,
OptMergeRS,
MergeLB,
@@ -164,6 +164,9 @@
double _cur_merge_heap_roots_time_ms;
double _cur_optional_merge_heap_roots_time_ms;
+ double _cur_prepare_merge_heap_roots_time_ms;
+ double _cur_optional_prepare_merge_heap_roots_time_ms;
+
double _cur_prepare_tlab_time_ms;
double _cur_resize_tlab_time_ms;
@@ -308,6 +311,14 @@
_cur_optional_merge_heap_roots_time_ms += ms;
}
+ void record_prepare_merge_heap_roots_time(double ms) {
+ _cur_prepare_merge_heap_roots_time_ms += ms;
+ }
+
+ void record_or_add_optional_prepare_merge_heap_roots_time(double ms) {
+ _cur_optional_prepare_merge_heap_roots_time_ms += ms;
+ }
+
void record_evac_fail_recalc_used_time(double ms) {
_cur_evac_fail_recalc_used = ms;
}
--- a/src/hotspot/share/gc/g1/g1HeapTransition.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -35,7 +35,6 @@
_old_length = g1_heap->old_regions_count();
_archive_length = g1_heap->archive_regions_count();
_humongous_length = g1_heap->humongous_regions_count();
- _metaspace_used_bytes = MetaspaceUtils::used_bytes();
}
G1HeapTransition::G1HeapTransition(G1CollectedHeap* g1_heap) : _g1_heap(g1_heap), _before(g1_heap) { }
@@ -131,5 +130,5 @@
log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
usage._humongous_used / K, ((after._humongous_length * HeapRegion::GrainBytes) - usage._humongous_used) / K);
- MetaspaceUtils::print_metaspace_change(_before._metaspace_used_bytes);
+ MetaspaceUtils::print_metaspace_change(_before._meta_sizes);
}
--- a/src/hotspot/share/gc/g1/g1HeapTransition.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,6 +26,7 @@
#define SHARE_GC_G1_G1HEAPTRANSITION_HPP
#include "gc/shared/plab.hpp"
+#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
class G1CollectedHeap;
@@ -36,7 +37,7 @@
size_t _old_length;
size_t _archive_length;
size_t _humongous_length;
- size_t _metaspace_used_bytes;
+ const metaspace::MetaspaceSizesSnapshot _meta_sizes;
Data(G1CollectedHeap* g1_heap);
};
--- a/src/hotspot/share/gc/g1/g1HotCardCache.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1HotCardCache.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "gc/g1/g1CardTableEntryClosure.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1DirtyCardQueue.hpp"
#include "gc/g1/g1HotCardCache.hpp"
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -43,7 +43,7 @@
size_t optional_cset_length)
: _g1h(g1h),
_refs(g1h->task_queue(worker_id)),
- _dcq(&g1h->dirty_card_queue_set()),
+ _rdcq(&g1h->redirty_cards_queue_set()),
_ct(g1h->card_table()),
_closures(NULL),
_plab_allocator(NULL),
@@ -88,7 +88,7 @@
// Pass locally gathered statistics to global state.
void G1ParScanThreadState::flush(size_t* surviving_young_words) {
- _dcq.flush();
+ _rdcq.flush();
// Update allocation statistics.
_plab_allocator->flush_and_retire_stats();
_g1h->policy()->record_age_table(&_age_table);
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -27,7 +27,7 @@
#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.hpp"
-#include "gc/g1/g1DirtyCardQueue.hpp"
+#include "gc/g1/g1RedirtyCardsQueue.hpp"
#include "gc/g1/g1OopClosures.hpp"
#include "gc/g1/g1Policy.hpp"
#include "gc/g1/g1RemSet.hpp"
@@ -46,7 +46,7 @@
class G1ParScanThreadState : public CHeapObj<mtGC> {
G1CollectedHeap* _g1h;
RefToScanQueue* _refs;
- G1DirtyCardQueue _dcq;
+ G1RedirtyCardsQueue _rdcq;
G1CardTable* _ct;
G1EvacuationRootClosures* _closures;
@@ -81,7 +81,7 @@
#define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
- G1DirtyCardQueue& dirty_card_queue() { return _dcq; }
+ G1RedirtyCardsQueue& redirty_cards_queue() { return _rdcq; }
G1CardTable* ct() { return _ct; }
G1HeapRegionAttr dest(G1HeapRegionAttr original) const {
@@ -133,7 +133,7 @@
size_t card_index = ct()->index_for(p);
// If the card hasn't been added to the buffer, do it.
if (_last_enqueued_card != card_index) {
- dirty_card_queue().enqueue(ct()->byte_for_index(card_index));
+ redirty_cards_queue().enqueue(ct()->byte_for_index(card_index));
_last_enqueued_card = card_index;
}
}
--- a/src/hotspot/share/gc/g1/g1Policy.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1Policy.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -684,7 +684,9 @@
if (remset_cards_scanned > 10) {
double avg_time_remset_scan = ((average_time_ms(G1GCPhaseTimes::ScanHR) + average_time_ms(G1GCPhaseTimes::OptScanHR)) *
remset_cards_scanned / total_cards_scanned) +
- average_time_ms(G1GCPhaseTimes::MergeRS);
+ average_time_ms(G1GCPhaseTimes::MergeER) +
+ average_time_ms(G1GCPhaseTimes::MergeRS) +
+ average_time_ms(G1GCPhaseTimes::OptMergeRS);
cost_per_remset_card_ms = avg_time_remset_scan / remset_cards_scanned;
_analytics->report_cost_per_remset_card_ms(cost_per_remset_card_ms, this_pause_was_young_only);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1RedirtyCardsQueue.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
+
+// G1RedirtyCardsBufferList
+
+G1RedirtyCardsBufferList::G1RedirtyCardsBufferList() :
+ _head(NULL), _tail(NULL), _count(0) {}
+
+G1RedirtyCardsBufferList::G1RedirtyCardsBufferList(BufferNode* head,
+ BufferNode* tail,
+ size_t count) :
+ _head(head), _tail(tail), _count(count)
+{
+ assert((_head == NULL) == (_tail == NULL), "invariant");
+ assert((_head == NULL) == (_count == 0), "invariant");
+}
+
+// G1RedirtyCardsQueueBase::LocalQSet
+
+G1RedirtyCardsQueueBase::LocalQSet::LocalQSet(G1RedirtyCardsQueueSet* shared_qset) :
+ PtrQueueSet(),
+ _shared_qset(shared_qset),
+ _buffers()
+{
+ PtrQueueSet::initialize(_shared_qset->allocator());
+}
+
+G1RedirtyCardsQueueBase::LocalQSet::~LocalQSet() {
+ assert(_buffers._head == NULL, "unflushed qset");
+ assert(_buffers._tail == NULL, "invariant");
+ assert(_buffers._count == 0, "invariant");
+}
+
+void G1RedirtyCardsQueueBase::LocalQSet::enqueue_completed_buffer(BufferNode* node) {
+ ++_buffers._count;
+ node->set_next(_buffers._head);
+ _buffers._head = node;
+ if (_buffers._tail == NULL) {
+ _buffers._tail = node;
+ }
+}
+
+G1RedirtyCardsBufferList
+G1RedirtyCardsQueueBase::LocalQSet::take_all_completed_buffers() {
+ G1RedirtyCardsBufferList result = _buffers;
+ _buffers = G1RedirtyCardsBufferList();
+ return result;
+}
+
+void G1RedirtyCardsQueueBase::LocalQSet::flush() {
+ _shared_qset->merge_bufferlist(this);
+}
+
+// G1RedirtyCardsQueue
+
+G1RedirtyCardsQueue::G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset) :
+ G1RedirtyCardsQueueBase(qset), // Init _local_qset before passing to PtrQueue.
+ PtrQueue(&_local_qset, true /* active (always) */)
+{}
+
+G1RedirtyCardsQueue::~G1RedirtyCardsQueue() {
+ flush();
+}
+
+void G1RedirtyCardsQueue::handle_completed_buffer() {
+ enqueue_completed_buffer();
+}
+
+void G1RedirtyCardsQueue::flush() {
+ flush_impl();
+ _local_qset.flush();
+}
+
+// G1RedirtyCardsQueueSet
+
+G1RedirtyCardsQueueSet::G1RedirtyCardsQueueSet() :
+ PtrQueueSet(),
+ _list(),
+ _count(0),
+ _tail(NULL)
+ DEBUG_ONLY(COMMA _collecting(true))
+{}
+
+G1RedirtyCardsQueueSet::~G1RedirtyCardsQueueSet() {
+ verify_empty();
+}
+
+#ifdef ASSERT
+void G1RedirtyCardsQueueSet::verify_empty() const {
+ assert(_list.empty(), "precondition");
+ assert(_tail == NULL, "invariant");
+ assert(_count == 0, "invariant");
+}
+#endif // ASSERT
+
+BufferNode* G1RedirtyCardsQueueSet::all_completed_buffers() const {
+ DEBUG_ONLY(_collecting = false;)
+ return _list.top();
+}
+
+G1RedirtyCardsBufferList G1RedirtyCardsQueueSet::take_all_completed_buffers() {
+ DEBUG_ONLY(_collecting = false;)
+ G1RedirtyCardsBufferList result(_list.pop_all(), _tail, _count);
+ _tail = NULL;
+ _count = 0;
+ DEBUG_ONLY(_collecting = true;)
+ return result;
+}
+
+void G1RedirtyCardsQueueSet::update_tail(BufferNode* node) {
+ // Node is the tail of a (possibly single element) list just prepended to
+ // _list. If, after that prepend, node's follower is NULL, then node is
+ // also the tail of _list, so record it as such.
+ if (node->next() == NULL) {
+ assert(_tail == NULL, "invariant");
+ _tail = node;
+ }
+}
+
+void G1RedirtyCardsQueueSet::enqueue_completed_buffer(BufferNode* node) {
+ assert(_collecting, "precondition");
+ Atomic::inc(&_count);
+ _list.push(*node);
+ update_tail(node);
+}
+
+void G1RedirtyCardsQueueSet::merge_bufferlist(LocalQSet* src) {
+ assert(_collecting, "precondition");
+ const G1RedirtyCardsBufferList from = src->take_all_completed_buffers();
+ if (from._head != NULL) {
+ assert(from._tail != NULL, "invariant");
+ Atomic::add(from._count, &_count);
+ _list.prepend(*from._head, *from._tail);
+ update_tail(from._tail);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP
+#define SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP
+
+#include "gc/shared/ptrQueue.hpp"
+#include "memory/allocation.hpp"
+#include "memory/padded.hpp"
+
+class G1CardTableEntryClosure;
+class G1RedirtyCardsQueue;
+class G1RedirtyCardsQueueSet;
+
+struct G1RedirtyCardsBufferList {
+ BufferNode* _head;
+ BufferNode* _tail;
+ size_t _count;
+
+ G1RedirtyCardsBufferList();
+ G1RedirtyCardsBufferList(BufferNode* head, BufferNode* tail, size_t count);
+};
+
+// Provide G1RedirtyCardsQueue with a thread-local qset. It provides an
+// uncontended staging area for completed buffers, to be flushed to the
+// shared qset en masse. Using the "base from member" idiom so the local
+// qset is constructed before being passed to the PtrQueue constructor.
+class G1RedirtyCardsQueueBase {
+ friend class G1RedirtyCardsQueue;
+ friend class G1RedirtyCardsQueueSet;
+
+ class LocalQSet : public PtrQueueSet {
+ G1RedirtyCardsQueueSet* _shared_qset;
+ G1RedirtyCardsBufferList _buffers;
+
+ public:
+ LocalQSet(G1RedirtyCardsQueueSet* shared_qset);
+ ~LocalQSet();
+
+ // Add the buffer to the local list.
+ virtual void enqueue_completed_buffer(BufferNode* node);
+
+ // Transfer all completed buffers to the shared qset.
+ void flush();
+
+ G1RedirtyCardsBufferList take_all_completed_buffers();
+ };
+
+ G1RedirtyCardsQueueBase(G1RedirtyCardsQueueSet* shared_qset) :
+ _local_qset(shared_qset) {}
+
+ ~G1RedirtyCardsQueueBase() {}
+
+ LocalQSet _local_qset;
+};
+
+// Worker-local queues of card table entries.
+class G1RedirtyCardsQueue : private G1RedirtyCardsQueueBase, public PtrQueue {
+protected:
+ virtual void handle_completed_buffer();
+
+public:
+ G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset);
+
+ // Flushes the queue.
+ ~G1RedirtyCardsQueue();
+
+ // Flushes all enqueued cards to qset.
+ void flush();
+};
+
+// Card table entries to be redirtied and the cards reprocessed later.
+// Has two phases, collecting and processing. During the collecting
+// phase buffers are added to the set. Once collecting is complete and
+// processing starts, buffers can no longer be added. Taking all the
+// collected (and processed) buffers reverts back to collecting, allowing
+// the set to be reused for another round of redirtying.
+class G1RedirtyCardsQueueSet : public PtrQueueSet {
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
+ BufferNode::Stack _list;
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
+ volatile size_t _count;
+ DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
+ BufferNode* _tail;
+ DEBUG_ONLY(mutable bool _collecting;)
+
+ typedef G1RedirtyCardsQueueBase::LocalQSet LocalQSet;
+
+ void update_tail(BufferNode* node);
+
+public:
+ G1RedirtyCardsQueueSet();
+ ~G1RedirtyCardsQueueSet();
+
+ using PtrQueueSet::initialize;
+
+ void verify_empty() const NOT_DEBUG_RETURN;
+
+ // Collect buffers. These functions are thread-safe.
+ // precondition: Must not be concurrent with buffer processing.
+ virtual void enqueue_completed_buffer(BufferNode* node);
+ void merge_bufferlist(LocalQSet* src);
+
+ // Processing phase operations.
+ // precondition: Must not be concurrent with buffer collection.
+ BufferNode* all_completed_buffers() const;
+ G1RedirtyCardsBufferList take_all_completed_buffers();
+};
+
+#endif // SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,6 +26,7 @@
#include "gc/g1/g1BarrierSet.hpp"
#include "gc/g1/g1BlockOffsetTable.inline.hpp"
#include "gc/g1/g1CardTable.inline.hpp"
+#include "gc/g1/g1CardTableEntryClosure.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1ConcurrentRefine.hpp"
#include "gc/g1/g1DirtyCardQueue.hpp"
@@ -183,259 +184,6 @@
}
};
- // Returns whether the given region contains cards we need to scan. The remembered
- // set and other sources may contain cards that
- // - are in uncommitted regions
- // - are located in the collection set
- // - are located in free regions
- // as we do not clean up remembered sets before merging heap roots.
- bool contains_cards_to_process(uint const region_idx) const {
- HeapRegion* hr = G1CollectedHeap::heap()->region_at_or_null(region_idx);
- return (hr != NULL && !hr->in_collection_set() && hr->is_old_or_humongous_or_archive());
- }
-
- class G1MergeCardSetClosure : public HeapRegionClosure {
- G1RemSetScanState* _scan_state;
- G1CardTable* _ct;
-
- uint _merged_sparse;
- uint _merged_fine;
- uint _merged_coarse;
-
- // Returns if the region contains cards we need to scan. If so, remember that
- // region in the current set of dirty regions.
- bool remember_if_interesting(uint const region_idx) {
- if (!_scan_state->contains_cards_to_process(region_idx)) {
- return false;
- }
- _scan_state->add_dirty_region(region_idx);
- return true;
- }
- public:
- G1MergeCardSetClosure(G1RemSetScanState* scan_state) :
- _scan_state(scan_state),
- _ct(G1CollectedHeap::heap()->card_table()),
- _merged_sparse(0),
- _merged_fine(0),
- _merged_coarse(0) { }
-
- void next_coarse_prt(uint const region_idx) {
- if (!remember_if_interesting(region_idx)) {
- return;
- }
-
- _merged_coarse++;
-
- size_t region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
- _ct->mark_region_dirty(region_base_idx, HeapRegion::CardsPerRegion);
- _scan_state->set_chunk_region_dirty(region_base_idx);
- }
-
- void next_fine_prt(uint const region_idx, BitMap* bm) {
- if (!remember_if_interesting(region_idx)) {
- return;
- }
-
- _merged_fine++;
-
- size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
- BitMap::idx_t cur = bm->get_next_one_offset(0);
- while (cur != bm->size()) {
- _ct->mark_clean_as_dirty(region_base_idx + cur);
- _scan_state->set_chunk_dirty(region_base_idx + cur);
- cur = bm->get_next_one_offset(cur + 1);
- }
- }
-
- void next_sparse_prt(uint const region_idx, SparsePRTEntry::card_elem_t* cards, uint const num_cards) {
- if (!remember_if_interesting(region_idx)) {
- return;
- }
-
- _merged_sparse++;
-
- size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
- for (uint i = 0; i < num_cards; i++) {
- size_t card_idx = region_base_idx + cards[i];
- _ct->mark_clean_as_dirty(card_idx);
- _scan_state->set_chunk_dirty(card_idx);
- }
- }
-
- virtual bool do_heap_region(HeapRegion* r) {
- assert(r->in_collection_set() || r->is_starts_humongous(), "must be");
-
- HeapRegionRemSet* rem_set = r->rem_set();
- if (!rem_set->is_empty()) {
- rem_set->iterate_prts(*this);
- }
-
- return false;
- }
-
- size_t merged_sparse() const { return _merged_sparse; }
- size_t merged_fine() const { return _merged_fine; }
- size_t merged_coarse() const { return _merged_coarse; }
- };
-
- // Visitor for the remembered sets of humongous candidate regions to merge their
- // remembered set into the card table.
- class G1FlushHumongousCandidateRemSets : public HeapRegionClosure {
- G1MergeCardSetClosure _cl;
-
- public:
- G1FlushHumongousCandidateRemSets(G1RemSetScanState* scan_state) : _cl(scan_state) { }
-
- virtual bool do_heap_region(HeapRegion* r) {
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
- if (!r->is_starts_humongous() ||
- !g1h->region_attr(r->hrm_index()).is_humongous() ||
- r->rem_set()->is_empty()) {
- return false;
- }
-
- guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
- "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
-
- _cl.do_heap_region(r);
-
- // We should only clear the card based remembered set here as we will not
- // implicitly rebuild anything else during eager reclaim. Note that at the moment
- // (and probably never) we do not enter this path if there are other kind of
- // remembered sets for this region.
- r->rem_set()->clear_locked(true /* only_cardset */);
- // Clear_locked() above sets the state to Empty. However we want to continue
- // collecting remembered set entries for humongous regions that were not
- // reclaimed.
- r->rem_set()->set_state_complete();
-#ifdef ASSERT
- G1HeapRegionAttr region_attr = g1h->region_attr(r->hrm_index());
- assert(region_attr.needs_remset_update(), "must be");
-#endif
- assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
-
- return false;
- }
-
- size_t merged_sparse() const { return _cl.merged_sparse(); }
- size_t merged_fine() const { return _cl.merged_fine(); }
- size_t merged_coarse() const { return _cl.merged_coarse(); }
- };
-
- // Visitor for the log buffer entries to merge them into the card table.
- class G1MergeLogBufferCardsClosure : public G1CardTableEntryClosure {
- G1RemSetScanState* _scan_state;
- G1CardTable* _ct;
-
- size_t _cards_dirty;
- size_t _cards_skipped;
- public:
- G1MergeLogBufferCardsClosure(G1CollectedHeap* g1h, G1RemSetScanState* scan_state) :
- _scan_state(scan_state), _ct(g1h->card_table()), _cards_dirty(0), _cards_skipped(0)
- {}
-
- bool do_card_ptr(CardValue* card_ptr, uint worker_i) {
- // The only time we care about recording cards that
- // contain references that point into the collection set
- // is during RSet updating within an evacuation pause.
- // In this case worker_id should be the id of a GC worker thread.
- assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-
- uint const region_idx = _ct->region_idx_for(card_ptr);
-
- // The second clause must come after - the log buffers might contain cards to uncommited
- // regions.
- // This code may count duplicate entries in the log buffers (even if rare) multiple
- // times.
- if (_scan_state->contains_cards_to_process(region_idx) && (*card_ptr == G1CardTable::dirty_card_val())) {
- _scan_state->add_dirty_region(region_idx);
- _scan_state->set_chunk_dirty(_ct->index_for_cardvalue(card_ptr));
- _cards_dirty++;
- } else {
- // We may have had dirty cards in the (initial) collection set (or the
- // young regions which are always in the initial collection set). We do
- // not fix their cards here: we already added these regions to the set of
- // regions to clear the card table at the end during the prepare() phase.
- _cards_skipped++;
- }
- return true;
- }
-
- size_t cards_dirty() const { return _cards_dirty; }
- size_t cards_skipped() const { return _cards_skipped; }
- };
-
- class G1MergeHeapRootsTask : public AbstractGangTask {
- HeapRegionClaimer _hr_claimer;
- G1RemSetScanState* _scan_state;
- bool _remembered_set_only;
-
- G1GCPhaseTimes::GCParPhases _merge_phase;
-
- volatile bool _fast_reclaim_handled;
-
- public:
- G1MergeHeapRootsTask(G1RemSetScanState* scan_state, uint num_workers, bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase) :
- AbstractGangTask("G1 Merge Heap Roots"),
- _hr_claimer(num_workers),
- _scan_state(scan_state),
- _remembered_set_only(remembered_set_only),
- _merge_phase(merge_phase),
- _fast_reclaim_handled(false) { }
-
- virtual void work(uint worker_id) {
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- G1GCPhaseTimes* p = g1h->phase_times();
-
- // We schedule flushing the remembered sets of humongous fast reclaim candidates
- // onto the card table first to allow the remaining parallelized tasks hide it.
- if (!_remembered_set_only &&
- p->fast_reclaim_humongous_candidates() > 0 &&
- !_fast_reclaim_handled &&
- !Atomic::cmpxchg(true, &_fast_reclaim_handled, false)) {
-
- G1FlushHumongousCandidateRemSets cl(_scan_state);
- g1h->heap_region_iterate(&cl);
-
- p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse);
- p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine);
- p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse);
- }
-
- // Merge remembered sets of current candidates.
- {
- G1GCParPhaseTimesTracker x(p, _merge_phase, worker_id, !_remembered_set_only /* must_record */);
- G1MergeCardSetClosure cl(_scan_state);
- g1h->collection_set_iterate_increment_from(&cl, &_hr_claimer, worker_id);
-
- p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse);
- p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine);
- p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse);
- }
-
- // Apply closure to log entries in the HCC.
- if (!_remembered_set_only && G1HotCardCache::default_use_cache()) {
- assert(_merge_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
- G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeHCC, worker_id);
- G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
- g1h->iterate_hcc_closure(&cl, worker_id);
- }
-
- // Now apply the closure to all remaining log entries.
- if (!_remembered_set_only) {
- assert(_merge_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
- G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeLB, worker_id);
-
- G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
- g1h->iterate_dirty_card_closure(&cl, worker_id);
-
- p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeLBDirtyCards);
- p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_skipped(), G1GCPhaseTimes::MergeLBSkippedCards);
- }
- }
- };
-
// Creates a snapshot of the current _top values at the start of collection to
// filter out card marks that we do not want to scan.
class G1ResetScanTopClosure : public HeapRegionClosure {
@@ -571,61 +319,46 @@
}
_all_dirty_regions = new G1DirtyRegions(_max_regions);
+ _next_dirty_regions = new G1DirtyRegions(_max_regions);
G1ResetScanTopClosure cl(this);
G1CollectedHeap::heap()->heap_region_iterate(&cl);
-
- _next_dirty_regions = new G1DirtyRegions(_max_regions);
}
- void print_merge_heap_roots_stats() {
- size_t num_scan_chunks = 0;
- for (uint i = 0; i < _max_regions * _scan_chunks_per_region; i++) {
- if (_region_scan_chunks[i]) {
- num_scan_chunks++;
- }
- }
- size_t num_visited_cards = num_scan_chunks * CardsPerChunk;
- size_t total_dirty_region_cards = _next_dirty_regions->size() * HeapRegion::CardsPerRegion;
+ void prepare_for_merge_heap_roots() {
+ _all_dirty_regions->merge(_next_dirty_regions);
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- size_t total_old_region_cards =
- (g1h->num_regions() - (g1h->num_free_regions() - g1h->collection_set()->cur_length())) * HeapRegion::CardsPerRegion;
+ _next_dirty_regions->reset();
+ for (size_t i = 0; i < _max_regions; i++) {
+ _card_table_scan_state[i] = 0;
+ }
- log_debug(gc,remset)("Visited cards " SIZE_FORMAT " Total dirty " SIZE_FORMAT " (%.2lf%%) Total old " SIZE_FORMAT " (%.2lf%%)",
- num_visited_cards,
- total_dirty_region_cards,
- percent_of(num_visited_cards, total_dirty_region_cards),
- total_old_region_cards,
- percent_of(num_visited_cards, total_old_region_cards));
+ ::memset(_region_scan_chunks, false, _max_regions * _scan_chunks_per_region * sizeof(*_region_scan_chunks));
}
- void merge_heap_roots(WorkGang* workers, bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase) {
- {
- _all_dirty_regions->merge(_next_dirty_regions);
- _next_dirty_regions->reset();
- for (size_t i = 0; i < _max_regions; i++) {
- _card_table_scan_state[i] = 0;
- }
-
- ::memset(_region_scan_chunks, false, _max_regions * _scan_chunks_per_region * sizeof(*_region_scan_chunks));
- }
-
- size_t const increment_length = G1CollectedHeap::heap()->collection_set()->increment_length();
+ // Returns whether the given region contains cards we need to scan. The remembered
+ // set and other sources may contain cards that
+ // - are in uncommitted regions
+ // - are located in the collection set
+ // - are located in free regions
+ // as we do not clean up remembered sets before merging heap roots.
+ bool contains_cards_to_process(uint const region_idx) const {
+ HeapRegion* hr = G1CollectedHeap::heap()->region_at_or_null(region_idx);
+ return (hr != NULL && !hr->in_collection_set() && hr->is_old_or_humongous_or_archive());
+ }
- uint const num_workers = !remembered_set_only ? workers->active_workers() :
- MIN2(workers->active_workers(), (uint)increment_length);
+ size_t num_visited_cards() const {
+ size_t result = 0;
+ for (uint i = 0; i < _max_regions * _scan_chunks_per_region; i++) {
+ if (_region_scan_chunks[i]) {
+ result++;
+ }
+ }
+ return result * CardsPerChunk;
+ }
- {
- G1MergeHeapRootsTask cl(this, num_workers, remembered_set_only, merge_phase);
- log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " regions",
- cl.name(), num_workers, increment_length);
- workers->run_task(&cl, num_workers);
- }
-
- if (log_is_enabled(Debug, gc, remset)) {
- print_merge_heap_roots_stats();
- }
+ size_t num_cards_in_dirty_regions() const {
+ return _next_dirty_regions->size() * HeapRegion::CardsPerRegion;
}
void set_chunk_region_dirty(size_t const region_card_idx) {
@@ -912,11 +645,20 @@
Tickspan _rem_set_root_scan_time;
Tickspan _rem_set_trim_partially_time;
- void scan_memregion(uint region_idx_for_card, MemRegion mr) {
+ // The address to which this thread already scanned (walked the heap) up to during
+ // card scanning (exclusive).
+ HeapWord* _scanned_to;
+
+ HeapWord* scan_memregion(uint region_idx_for_card, MemRegion mr) {
HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
G1ScanCardClosure card_cl(_g1h, _pss);
- card_region->oops_on_card_seq_iterate_careful<true>(mr, &card_cl);
+
+ HeapWord* const scanned_to = card_region->oops_on_memregion_seq_iterate_careful<true>(mr, &card_cl);
+ assert(scanned_to != NULL, "Should be able to scan range");
+ assert(scanned_to >= mr.end(), "Scanned to " PTR_FORMAT " less than range " PTR_FORMAT, p2i(scanned_to), p2i(mr.end()));
+
_pss->trim_queue_partially();
+ return scanned_to;
}
void do_claimed_block(uint const region_idx_for_card, size_t const first_card, size_t const num_cards) {
@@ -931,8 +673,12 @@
return;
}
- MemRegion mr(card_start, MIN2(card_start + ((size_t)num_cards << BOTConstants::LogN_words), top));
- scan_memregion(region_idx_for_card, mr);
+ HeapWord* scan_end = MIN2(card_start + (num_cards << BOTConstants::LogN_words), top);
+ if (_scanned_to >= scan_end) {
+ return;
+ }
+ MemRegion mr(MAX2(card_start, _scanned_to), scan_end);
+ _scanned_to = scan_memregion(region_idx_for_card, mr);
_cards_scanned += num_cards;
}
@@ -951,6 +697,12 @@
G1CardTableChunkClaimer claim(_scan_state, region_idx);
+ // Set the current scan "finger" to NULL for every heap region to scan. Since
+ // the claim value is monotonically increasing, the check to not scan below this
+ // will filter out objects spanning chunks within the region too then, as opposed
+ // to resetting this value for every claim.
+ _scanned_to = NULL;
+
while (claim.has_next()) {
size_t const region_card_base_idx = ((size_t)region_idx << HeapRegion::LogCardsPerRegion) + claim.value();
CardTable::CardValue* const base_addr = _ct->byte_for_index(region_card_base_idx);
@@ -994,7 +746,8 @@
_blocks_scanned(0),
_chunks_claimed(0),
_rem_set_root_scan_time(),
- _rem_set_trim_partially_time() {
+ _rem_set_trim_partially_time(),
+ _scanned_to(NULL) {
}
bool do_heap_region(HeapRegion* r) {
@@ -1149,8 +902,302 @@
_scan_state->prepare();
}
-void G1RemSet::merge_heap_roots(bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase) {
- _scan_state->merge_heap_roots(_g1h->workers(), remembered_set_only, merge_phase);
+class G1MergeHeapRootsTask : public AbstractGangTask {
+
+ // Visitor for remembered sets, dropping entries onto the card table.
+ class G1MergeCardSetClosure : public HeapRegionClosure {
+ G1RemSetScanState* _scan_state;
+ G1CardTable* _ct;
+
+ uint _merged_sparse;
+ uint _merged_fine;
+ uint _merged_coarse;
+
+ // Returns if the region contains cards we need to scan. If so, remember that
+ // region in the current set of dirty regions.
+ bool remember_if_interesting(uint const region_idx) {
+ if (!_scan_state->contains_cards_to_process(region_idx)) {
+ return false;
+ }
+ _scan_state->add_dirty_region(region_idx);
+ return true;
+ }
+ public:
+ G1MergeCardSetClosure(G1RemSetScanState* scan_state) :
+ _scan_state(scan_state),
+ _ct(G1CollectedHeap::heap()->card_table()),
+ _merged_sparse(0),
+ _merged_fine(0),
+ _merged_coarse(0) { }
+
+ void next_coarse_prt(uint const region_idx) {
+ if (!remember_if_interesting(region_idx)) {
+ return;
+ }
+
+ _merged_coarse++;
+
+ size_t region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
+ _ct->mark_region_dirty(region_base_idx, HeapRegion::CardsPerRegion);
+ _scan_state->set_chunk_region_dirty(region_base_idx);
+ }
+
+ void next_fine_prt(uint const region_idx, BitMap* bm) {
+ if (!remember_if_interesting(region_idx)) {
+ return;
+ }
+
+ _merged_fine++;
+
+ size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
+ BitMap::idx_t cur = bm->get_next_one_offset(0);
+ while (cur != bm->size()) {
+ _ct->mark_clean_as_dirty(region_base_idx + cur);
+ _scan_state->set_chunk_dirty(region_base_idx + cur);
+ cur = bm->get_next_one_offset(cur + 1);
+ }
+ }
+
+ void next_sparse_prt(uint const region_idx, SparsePRTEntry::card_elem_t* cards, uint const num_cards) {
+ if (!remember_if_interesting(region_idx)) {
+ return;
+ }
+
+ _merged_sparse++;
+
+ size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
+ for (uint i = 0; i < num_cards; i++) {
+ size_t card_idx = region_base_idx + cards[i];
+ _ct->mark_clean_as_dirty(card_idx);
+ _scan_state->set_chunk_dirty(card_idx);
+ }
+ }
+
+ virtual bool do_heap_region(HeapRegion* r) {
+ assert(r->in_collection_set() || r->is_starts_humongous(), "must be");
+
+ HeapRegionRemSet* rem_set = r->rem_set();
+ if (!rem_set->is_empty()) {
+ rem_set->iterate_prts(*this);
+ }
+
+ return false;
+ }
+
+ size_t merged_sparse() const { return _merged_sparse; }
+ size_t merged_fine() const { return _merged_fine; }
+ size_t merged_coarse() const { return _merged_coarse; }
+ };
+
+ // Visitor for the remembered sets of humongous candidate regions to merge their
+ // remembered set into the card table.
+ class G1FlushHumongousCandidateRemSets : public HeapRegionClosure {
+ G1MergeCardSetClosure _cl;
+
+ public:
+ G1FlushHumongousCandidateRemSets(G1RemSetScanState* scan_state) : _cl(scan_state) { }
+
+ virtual bool do_heap_region(HeapRegion* r) {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+ if (!r->is_starts_humongous() ||
+ !g1h->region_attr(r->hrm_index()).is_humongous() ||
+ r->rem_set()->is_empty()) {
+ return false;
+ }
+
+ guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
+ "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
+
+ _cl.do_heap_region(r);
+
+ // We should only clear the card based remembered set here as we will not
+ // implicitly rebuild anything else during eager reclaim. Note that at the moment
+ // (and probably never) we do not enter this path if there are other kind of
+ // remembered sets for this region.
+ r->rem_set()->clear_locked(true /* only_cardset */);
+ // Clear_locked() above sets the state to Empty. However we want to continue
+ // collecting remembered set entries for humongous regions that were not
+ // reclaimed.
+ r->rem_set()->set_state_complete();
+#ifdef ASSERT
+ G1HeapRegionAttr region_attr = g1h->region_attr(r->hrm_index());
+ assert(region_attr.needs_remset_update(), "must be");
+#endif
+ assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
+
+ return false;
+ }
+
+ size_t merged_sparse() const { return _cl.merged_sparse(); }
+ size_t merged_fine() const { return _cl.merged_fine(); }
+ size_t merged_coarse() const { return _cl.merged_coarse(); }
+ };
+
+ // Visitor for the log buffer entries to merge them into the card table.
+ class G1MergeLogBufferCardsClosure : public G1CardTableEntryClosure {
+ G1RemSetScanState* _scan_state;
+ G1CardTable* _ct;
+
+ size_t _cards_dirty;
+ size_t _cards_skipped;
+ public:
+ G1MergeLogBufferCardsClosure(G1CollectedHeap* g1h, G1RemSetScanState* scan_state) :
+ _scan_state(scan_state), _ct(g1h->card_table()), _cards_dirty(0), _cards_skipped(0)
+ {}
+
+ bool do_card_ptr(CardValue* card_ptr, uint worker_i) {
+ // The only time we care about recording cards that
+ // contain references that point into the collection set
+ // is during RSet updating within an evacuation pause.
+ // In this case worker_id should be the id of a GC worker thread.
+ assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
+
+ uint const region_idx = _ct->region_idx_for(card_ptr);
+
+ // The second clause must come after - the log buffers might contain cards to uncommited
+ // regions.
+ // This code may count duplicate entries in the log buffers (even if rare) multiple
+ // times.
+ if (_scan_state->contains_cards_to_process(region_idx) && (*card_ptr == G1CardTable::dirty_card_val())) {
+ _scan_state->add_dirty_region(region_idx);
+ _scan_state->set_chunk_dirty(_ct->index_for_cardvalue(card_ptr));
+ _cards_dirty++;
+ } else {
+ // We may have had dirty cards in the (initial) collection set (or the
+ // young regions which are always in the initial collection set). We do
+ // not fix their cards here: we already added these regions to the set of
+ // regions to clear the card table at the end during the prepare() phase.
+ _cards_skipped++;
+ }
+ return true;
+ }
+
+ size_t cards_dirty() const { return _cards_dirty; }
+ size_t cards_skipped() const { return _cards_skipped; }
+ };
+
+ HeapRegionClaimer _hr_claimer;
+ G1RemSetScanState* _scan_state;
+ bool _initial_evacuation;
+
+ volatile bool _fast_reclaim_handled;
+
+public:
+ G1MergeHeapRootsTask(G1RemSetScanState* scan_state, uint num_workers, bool initial_evacuation) :
+ AbstractGangTask("G1 Merge Heap Roots"),
+ _hr_claimer(num_workers),
+ _scan_state(scan_state),
+ _initial_evacuation(initial_evacuation),
+ _fast_reclaim_handled(false) { }
+
+ virtual void work(uint worker_id) {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ G1GCPhaseTimes* p = g1h->phase_times();
+
+ G1GCPhaseTimes::GCParPhases merge_remset_phase = _initial_evacuation ?
+ G1GCPhaseTimes::MergeRS :
+ G1GCPhaseTimes::OptMergeRS;
+
+ // We schedule flushing the remembered sets of humongous fast reclaim candidates
+ // onto the card table first to allow the remaining parallelized tasks hide it.
+ if (_initial_evacuation &&
+ p->fast_reclaim_humongous_candidates() > 0 &&
+ !_fast_reclaim_handled &&
+ !Atomic::cmpxchg(true, &_fast_reclaim_handled, false)) {
+
+ G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeER, worker_id);
+
+ G1FlushHumongousCandidateRemSets cl(_scan_state);
+ g1h->heap_region_iterate(&cl);
+
+ p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse);
+ p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine);
+ p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse);
+ }
+
+ // Merge remembered sets of current candidates.
+ {
+ G1GCParPhaseTimesTracker x(p, merge_remset_phase, worker_id, _initial_evacuation /* must_record */);
+ G1MergeCardSetClosure cl(_scan_state);
+ g1h->collection_set_iterate_increment_from(&cl, &_hr_claimer, worker_id);
+
+ p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse);
+ p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine);
+ p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse);
+ }
+
+ // Apply closure to log entries in the HCC.
+ if (_initial_evacuation && G1HotCardCache::default_use_cache()) {
+ assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
+ G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeHCC, worker_id);
+ G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
+ g1h->iterate_hcc_closure(&cl, worker_id);
+ }
+
+ // Now apply the closure to all remaining log entries.
+ if (_initial_evacuation) {
+ assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
+ G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeLB, worker_id);
+
+ G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
+ g1h->iterate_dirty_card_closure(&cl, worker_id);
+
+ p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeLBDirtyCards);
+ p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_skipped(), G1GCPhaseTimes::MergeLBSkippedCards);
+ }
+ }
+};
+
+void G1RemSet::print_merge_heap_roots_stats() {
+ size_t num_visited_cards = _scan_state->num_visited_cards();
+
+ size_t total_dirty_region_cards = _scan_state->num_cards_in_dirty_regions();
+
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ size_t total_old_region_cards =
+ (g1h->num_regions() - (g1h->num_free_regions() - g1h->collection_set()->cur_length())) * HeapRegion::CardsPerRegion;
+
+ log_debug(gc,remset)("Visited cards " SIZE_FORMAT " Total dirty " SIZE_FORMAT " (%.2lf%%) Total old " SIZE_FORMAT " (%.2lf%%)",
+ num_visited_cards,
+ total_dirty_region_cards,
+ percent_of(num_visited_cards, total_dirty_region_cards),
+ total_old_region_cards,
+ percent_of(num_visited_cards, total_old_region_cards));
+}
+
+void G1RemSet::merge_heap_roots(bool initial_evacuation) {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+ {
+ Ticks start = Ticks::now();
+
+ _scan_state->prepare_for_merge_heap_roots();
+
+ Tickspan total = Ticks::now() - start;
+ if (initial_evacuation) {
+ g1h->phase_times()->record_prepare_merge_heap_roots_time(total.seconds() * 1000.0);
+ } else {
+ g1h->phase_times()->record_or_add_optional_prepare_merge_heap_roots_time(total.seconds() * 1000.0);
+ }
+ }
+
+ WorkGang* workers = g1h->workers();
+ size_t const increment_length = g1h->collection_set()->increment_length();
+
+ uint const num_workers = initial_evacuation ? workers->active_workers() :
+ MIN2(workers->active_workers(), (uint)increment_length);
+
+ {
+ G1MergeHeapRootsTask cl(_scan_state, num_workers, initial_evacuation);
+ log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " regions",
+ cl.name(), num_workers, increment_length);
+ workers->run_task(&cl, num_workers);
+ }
+
+ if (log_is_enabled(Debug, gc, remset)) {
+ print_merge_heap_roots_stats();
+ }
}
void G1RemSet::prepare_for_scan_heap_roots(uint region_idx) {
@@ -1292,7 +1339,7 @@
assert(!dirty_region.is_empty(), "sanity");
G1ConcurrentRefineOopClosure conc_refine_cl(_g1h, worker_i);
- if (r->oops_on_card_seq_iterate_careful<false>(dirty_region, &conc_refine_cl)) {
+ if (r->oops_on_memregion_seq_iterate_careful<false>(dirty_region, &conc_refine_cl) != NULL) {
_num_conc_refined_cards++; // Unsynchronized update, only used for logging.
return;
}
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -67,6 +67,7 @@
G1Policy* _g1p;
G1HotCardCache* _hot_card_cache;
+ void print_merge_heap_roots_stats();
public:
typedef CardTable::CardValue CardValue;
@@ -94,8 +95,8 @@
// Merge cards from various sources (remembered sets, hot card cache, log buffers)
// and calculate the cards that need to be scanned later (via scan_heap_roots()).
- // If remembered_set_only is set, only merge remembered set cards.
- void merge_heap_roots(bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase);
+ // If initial_evacuation is set, this is called during the initial evacuation.
+ void merge_heap_roots(bool initial_evacuation);
// Prepare for and cleanup after scanning the heap roots. Must be called
// once before and after in sequential code.
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -44,9 +44,6 @@
#include "runtime/mutex.hpp"
#include "services/management.hpp"
#include "utilities/macros.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
void G1RootProcessor::worker_has_discovered_all_strong_classes() {
assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
@@ -261,15 +258,6 @@
}
#endif
-#if INCLUDE_JVMCI
- if (EnableJVMCI) {
- G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMCIRoots, worker_i);
- if (_process_strong_tasks.try_claim_task(G1RP_PS_JVMCI_oops_do)) {
- JVMCI::oops_do(strong_roots);
- }
- }
-#endif
-
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
if (_process_strong_tasks.try_claim_task(G1RP_PS_SystemDictionary_oops_do)) {
--- a/src/hotspot/share/gc/g1/g1RootProcessor.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -64,7 +64,6 @@
G1RP_PS_jvmti_oops_do,
G1RP_PS_CodeCache_oops_do,
AOT_ONLY(G1RP_PS_aot_oops_do COMMA)
- JVMCI_ONLY(G1RP_PS_JVMCI_oops_do COMMA)
G1RP_PS_refProcessor_oops_do,
// Leave this one last.
G1RP_PS_NumElements
--- a/src/hotspot/share/gc/g1/heapRegion.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -289,14 +289,17 @@
// for the collection set.
double _predicted_elapsed_time_ms;
- // Iterate over the references in a humongous objects and apply the given closure
- // to them.
+ // Iterate over the references covered by the given MemRegion in a humongous
+ // object and apply the given closure to them.
// Humongous objects are allocated directly in the old-gen. So we need special
// handling for concurrent processing encountering an in-progress allocation.
+ // Returns the address after the last actually scanned or NULL if the area could
+ // not be scanned (That should only happen when invoked concurrently with the
+ // mutator).
template <class Closure, bool is_gc_active>
- inline bool do_oops_on_card_in_humongous(MemRegion mr,
- Closure* cl,
- G1CollectedHeap* g1h);
+ inline HeapWord* do_oops_on_memregion_in_humongous(MemRegion mr,
+ Closure* cl,
+ G1CollectedHeap* g1h);
// Returns the block size of the given (dead, potentially having its class unloaded) object
// starting at p extending to at most the prev TAMS using the given mark bitmap.
@@ -645,18 +648,16 @@
}
}
- // Iterate over the objects overlapping part of a card, applying cl
+ // Iterate over the objects overlapping the given memory region, applying cl
// to all references in the region. This is a helper for
// G1RemSet::refine_card*, and is tightly coupled with them.
- // mr is the memory region covered by the card, trimmed to the
- // allocated space for this region. Must not be empty.
+ // mr must not be empty. Must be trimmed to the allocated/parseable space in this region.
// This region must be old or humongous.
- // Returns true if the designated objects were successfully
- // processed, false if an unparsable part of the heap was
- // encountered; that only happens when invoked concurrently with the
- // mutator.
+ // Returns the next unscanned address if the designated objects were successfully
+ // processed, NULL if an unparseable part of the heap was encountered (That should
+ // only happen when invoked concurrently with the mutator).
template <bool is_gc_active, class Closure>
- inline bool oops_on_card_seq_iterate_careful(MemRegion mr, Closure* cl);
+ inline HeapWord* oops_on_memregion_seq_iterate_careful(MemRegion mr, Closure* cl);
size_t recorded_rs_length() const { return _recorded_rs_length; }
double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
--- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -257,9 +257,9 @@
}
template <class Closure, bool is_gc_active>
-bool HeapRegion::do_oops_on_card_in_humongous(MemRegion mr,
- Closure* cl,
- G1CollectedHeap* g1h) {
+HeapWord* HeapRegion::do_oops_on_memregion_in_humongous(MemRegion mr,
+ Closure* cl,
+ G1CollectedHeap* g1h) {
assert(is_humongous(), "precondition");
HeapRegion* sr = humongous_start_region();
oop obj = oop(sr->bottom());
@@ -271,41 +271,48 @@
// since the allocating thread could have performed a write to the
// card that might be missed otherwise.
if (!is_gc_active && (obj->klass_or_null_acquire() == NULL)) {
- return false;
+ return NULL;
}
// We have a well-formed humongous object at the start of sr.
// Only filler objects follow a humongous object in the containing
// regions, and we can ignore those. So only process the one
// humongous object.
- if (!g1h->is_obj_dead(obj, sr)) {
- if (obj->is_objArray() || (sr->bottom() < mr.start())) {
- // objArrays are always marked precisely, so limit processing
- // with mr. Non-objArrays might be precisely marked, and since
- // it's humongous it's worthwhile avoiding full processing.
- // However, the card could be stale and only cover filler
- // objects. That should be rare, so not worth checking for;
- // instead let it fall out from the bounded iteration.
- obj->oop_iterate(cl, mr);
- } else {
- // If obj is not an objArray and mr contains the start of the
- // obj, then this could be an imprecise mark, and we need to
- // process the entire object.
- obj->oop_iterate(cl);
- }
+ if (g1h->is_obj_dead(obj, sr)) {
+ // The object is dead. There can be no other object in this region, so return
+ // the end of that region.
+ return end();
}
- return true;
+ if (obj->is_objArray() || (sr->bottom() < mr.start())) {
+ // objArrays are always marked precisely, so limit processing
+ // with mr. Non-objArrays might be precisely marked, and since
+ // it's humongous it's worthwhile avoiding full processing.
+ // However, the card could be stale and only cover filler
+ // objects. That should be rare, so not worth checking for;
+ // instead let it fall out from the bounded iteration.
+ obj->oop_iterate(cl, mr);
+ return mr.end();
+ } else {
+ // If obj is not an objArray and mr contains the start of the
+ // obj, then this could be an imprecise mark, and we need to
+ // process the entire object.
+ int size = obj->oop_iterate_size(cl);
+ // We have scanned to the end of the object, but since there can be no objects
+ // after this humongous object in the region, we can return the end of the
+ // region if it is greater.
+ return MAX2((HeapWord*)obj + size, mr.end());
+ }
}
template <bool is_gc_active, class Closure>
-bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr,
- Closure* cl) {
+HeapWord* HeapRegion::oops_on_memregion_seq_iterate_careful(MemRegion mr,
+ Closure* cl) {
assert(MemRegion(bottom(), end()).contains(mr), "Card region not in heap region");
G1CollectedHeap* g1h = G1CollectedHeap::heap();
// Special handling for humongous regions.
if (is_humongous()) {
- return do_oops_on_card_in_humongous<Closure, is_gc_active>(mr, cl, g1h);
+ return do_oops_on_memregion_in_humongous<Closure, is_gc_active>(mr, cl, g1h);
}
assert(is_old() || is_archive(), "Wrongly trying to iterate over region %u type %s", _hrm_index, get_type_str());
@@ -334,7 +341,7 @@
#endif
const G1CMBitMap* const bitmap = g1h->concurrent_mark()->prev_mark_bitmap();
- do {
+ while (true) {
oop obj = oop(cur);
assert(oopDesc::is_oop(obj, true), "Not an oop at " PTR_FORMAT, p2i(cur));
assert(obj->klass_or_null() != NULL,
@@ -342,6 +349,7 @@
size_t size;
bool is_dead = is_obj_dead_with_size(obj, bitmap, &size);
+ bool is_precise = false;
cur += size;
if (!is_dead) {
@@ -355,11 +363,13 @@
obj->oop_iterate(cl);
} else {
obj->oop_iterate(cl, mr);
+ is_precise = true;
}
}
- } while (cur < end);
-
- return true;
+ if (cur >= end) {
+ return is_precise ? end : cur;
+ }
+ }
}
#endif // SHARE_GC_G1_HEAPREGION_INLINE_HPP
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -38,6 +38,7 @@
#include "gc/shared/strongRootsScope.hpp"
#include "logging/log.hpp"
#include "memory/metaspace.hpp"
+#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/ostream.hpp"
@@ -257,19 +258,18 @@
PreGCValues(ParallelScavengeHeap* heap) :
_heap_used(heap->used()),
_young_gen_used(heap->young_gen()->used_in_bytes()),
- _old_gen_used(heap->old_gen()->used_in_bytes()),
- _metadata_used(MetaspaceUtils::used_bytes()) { };
+ _old_gen_used(heap->old_gen()->used_in_bytes()) { }
size_t heap_used() const { return _heap_used; }
size_t young_gen_used() const { return _young_gen_used; }
size_t old_gen_used() const { return _old_gen_used; }
- size_t metadata_used() const { return _metadata_used; }
+ const metaspace::MetaspaceSizesSnapshot& metaspace_sizes() const { return _meta_sizes; }
private:
size_t _heap_used;
size_t _young_gen_used;
size_t _old_gen_used;
- size_t _metadata_used;
+ const metaspace::MetaspaceSizesSnapshot _meta_sizes;
};
// Class that can be used to print information about the
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/pcTasks.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -46,9 +46,6 @@
#include "runtime/vmThread.hpp"
#include "services/management.hpp"
#include "utilities/stack.inline.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
//
// ThreadRootsMarkingTask
@@ -124,12 +121,6 @@
AOTLoader::oops_do(&mark_and_push_closure);
break;
-#if INCLUDE_JVMCI
- case jvmci:
- JVMCI::oops_do(&mark_and_push_closure);
- break;
-#endif
-
default:
fatal("Unknown root type");
}
--- a/src/hotspot/share/gc/parallel/pcTasks.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/pcTasks.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -99,7 +99,6 @@
system_dictionary = 7,
class_loader_data = 8,
code_cache = 9
- JVMCI_ONLY(COMMA jvmci = 10)
};
private:
RootType _root_type;
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -193,11 +193,7 @@
BiasedLocking::preserve_marks();
- // Capture metadata size before collection for sizing.
- size_t metadata_prev_used = MetaspaceUtils::used_bytes();
-
- size_t old_gen_prev_used = old_gen->used_in_bytes();
- size_t young_gen_prev_used = young_gen->used_in_bytes();
+ const PreGCValues pre_gc_values(heap);
allocate_stacks();
@@ -352,9 +348,9 @@
accumulated_time()->stop();
}
- young_gen->print_used_change(young_gen_prev_used);
- old_gen->print_used_change(old_gen_prev_used);
- MetaspaceUtils::print_metaspace_change(metadata_prev_used);
+ young_gen->print_used_change(pre_gc_values.young_gen_used());
+ old_gen->print_used_change(pre_gc_values.old_gen_used());
+ MetaspaceUtils::print_metaspace_change(pre_gc_values.metaspace_sizes());
// Track memory usage and detect low memory
MemoryService::track_memory_usage();
@@ -528,7 +524,6 @@
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
//ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
AOT_ONLY(AOTLoader::oops_do(mark_and_push_closure());)
- JVMCI_ONLY(JVMCI::oops_do(mark_and_push_closure());)
}
// Flush marking stack.
@@ -624,8 +619,6 @@
CodeCache::blobs_do(&adjust_from_blobs);
AOT_ONLY(AOTLoader::oops_do(adjust_pointer_closure());)
- JVMCI_ONLY(JVMCI::oops_do(adjust_pointer_closure());)
-
ref_processor()->weak_oops_do(adjust_pointer_closure());
PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1779,7 +1779,7 @@
// miscellaneous bookkeeping.
pre_compact();
- PreGCValues pre_gc_values(heap);
+ const PreGCValues pre_gc_values(heap);
// Get the compaction manager reserved for the VM thread.
ParCompactionManager* const vmthread_cm =
@@ -1925,7 +1925,7 @@
young_gen->print_used_change(pre_gc_values.young_gen_used());
old_gen->print_used_change(pre_gc_values.old_gen_used());
- MetaspaceUtils::print_metaspace_change(pre_gc_values.metadata_used());
+ MetaspaceUtils::print_metaspace_change(pre_gc_values.metaspace_sizes());
// Track memory usage and detect low memory
MemoryService::track_memory_usage();
@@ -2127,7 +2127,6 @@
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
- JVMCI_ONLY(q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmci));)
if (active_gc_threads > 1) {
for (uint j = 0; j < active_gc_threads; j++) {
@@ -2217,8 +2216,6 @@
CodeCache::blobs_do(&adjust_from_blobs);
AOT_ONLY(AOTLoader::oops_do(&oop_closure);)
- JVMCI_ONLY(JVMCI::oops_do(&oop_closure);)
-
ref_processor()->weak_oops_do(&oop_closure);
// Roots were visited so references into the young gen in roots
// may have been scanned. Process them also.
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -328,7 +328,7 @@
reference_processor()->enable_discovery();
reference_processor()->setup_policy(false);
- PreGCValues pre_gc_values(heap);
+ const PreGCValues pre_gc_values(heap);
// Reset our survivor overflow.
set_survivor_overflow(false);
@@ -379,7 +379,6 @@
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
- JVMCI_ONLY(q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmci));)
TaskTerminator terminator(active_workers,
(TaskQueueSetSuper*) promotion_manager->stack_array_depth());
@@ -601,7 +600,7 @@
young_gen->print_used_change(pre_gc_values.young_gen_used());
old_gen->print_used_change(pre_gc_values.old_gen_used());
- MetaspaceUtils::print_metaspace_change(pre_gc_values.metadata_used());
+ MetaspaceUtils::print_metaspace_change(pre_gc_values.metaspace_sizes());
// Track memory usage and detect low memory
MemoryService::track_memory_usage();
--- a/src/hotspot/share/gc/parallel/psTasks.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psTasks.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -44,9 +44,6 @@
#include "runtime/thread.hpp"
#include "runtime/vmThread.hpp"
#include "services/management.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
//
// ScavengeRootsTask
@@ -106,12 +103,6 @@
}
break;
-#if INCLUDE_JVMCI
- case jvmci:
- JVMCI::oops_do(&roots_closure);
- break;
-#endif
-
default:
fatal("Unknown root type");
}
--- a/src/hotspot/share/gc/parallel/psTasks.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psTasks.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -61,7 +61,6 @@
management = 7,
jvmti = 8,
code_cache = 9
- JVMCI_ONLY(COMMA jvmci = 10)
};
private:
RootType _root_type;
--- a/src/hotspot/share/gc/shared/c1/barrierSetC1.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/c1/barrierSetC1.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -137,6 +137,8 @@
virtual LIR_Opr resolve(LIRGenerator* gen, DecoratorSet decorators, LIR_Opr obj);
+ virtual const char* rtcall_name_for_address(address entry) { return NULL; }
+
virtual void generate_c1_runtime_stubs(BufferBlob* buffer_blob) {}
};
--- a/src/hotspot/share/gc/shared/gcBehaviours.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/gcBehaviours.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -64,7 +64,7 @@
bool ClosureIsUnloadingBehaviour::is_unloading(CompiledMethod* cm) const {
if (cm->is_nmethod()) {
IsCompiledMethodUnloadingOopClosure cl(_cl);
- static_cast<nmethod*>(cm)->oops_do(&cl);
+ static_cast<nmethod*>(cm)->oops_do(&cl, true /* allow_dead */);
return cl.is_unloading();
} else {
return false;
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -575,9 +575,6 @@
ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy());
- const size_t metadata_prev_used = MetaspaceUtils::used_bytes();
-
-
FlagSetting fl(_is_gc_active, true);
bool complete = full && (max_generation == OldGen);
@@ -586,6 +583,7 @@
size_t young_prev_used = _young_gen->used();
size_t old_prev_used = _old_gen->used();
+ const metaspace::MetaspaceSizesSnapshot prev_meta_sizes;
bool run_verification = total_collections() >= VerifyGCStartAt;
bool prepared_for_verification = false;
@@ -628,7 +626,7 @@
_young_gen->compute_new_size();
print_heap_change(young_prev_used, old_prev_used);
- MetaspaceUtils::print_metaspace_change(metadata_prev_used);
+ MetaspaceUtils::print_metaspace_change(prev_meta_sizes);
// Track memory usage and detect low memory after GC finishes
MemoryService::track_memory_usage();
@@ -687,7 +685,7 @@
update_full_collections_completed();
print_heap_change(young_prev_used, old_prev_used);
- MetaspaceUtils::print_metaspace_change(metadata_prev_used);
+ MetaspaceUtils::print_metaspace_change(prev_meta_sizes);
// Track memory usage and detect low memory after GC finishes
MemoryService::track_memory_usage();
@@ -863,11 +861,6 @@
AOTLoader::oops_do(strong_roots);
}
#endif
-#if INCLUDE_JVMCI
- if (EnableJVMCI && _process_strong_tasks->try_claim_task(GCH_PS_jvmci_oops_do)) {
- JVMCI::oops_do(strong_roots);
- }
-#endif
if (_process_strong_tasks->try_claim_task(GCH_PS_SystemDictionary_oops_do)) {
SystemDictionary::oops_do(strong_roots);
}
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -114,7 +114,6 @@
GCH_PS_jvmti_oops_do,
GCH_PS_CodeCache_oops_do,
AOT_ONLY(GCH_PS_aot_oops_do COMMA)
- JVMCI_ONLY(GCH_PS_jvmci_oops_do COMMA)
GCH_PS_younger_gens,
// Leave this one last.
GCH_PS_NumElements
--- a/src/hotspot/share/gc/shared/generation.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/generation.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -68,12 +68,6 @@
return gch->old_gen_spec()->init_size();
}
-// This is for CMS. It returns stable monotonic used space size.
-// Remove this when CMS is removed.
-size_t Generation::used_stable() const {
- return used();
-}
-
size_t Generation::max_capacity() const {
return reserved().byte_size();
}
--- a/src/hotspot/share/gc/shared/generation.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/generation.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -156,7 +156,6 @@
virtual size_t capacity() const = 0; // The maximum number of object bytes the
// generation can currently hold.
virtual size_t used() const = 0; // The number of used bytes in the gen.
- virtual size_t used_stable() const; // The number of used bytes for memory monitoring tools.
virtual size_t free() const = 0; // The number of free bytes in the gen.
// Support for java.lang.Runtime.maxMemory(); see CollectedHeap.
--- a/src/hotspot/share/gc/shared/memAllocator.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/memAllocator.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -370,6 +370,10 @@
HeapWord* mem = mem_allocate(allocation);
if (mem != NULL) {
obj = initialize(mem);
+ } else {
+ // The unhandled oop detector will poison local variable obj,
+ // so reset it to NULL if mem is NULL.
+ obj = NULL;
}
}
return obj;
--- a/src/hotspot/share/gc/shared/oopStorage.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/oopStorage.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -35,6 +35,7 @@
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.hpp"
@@ -414,14 +415,6 @@
oop* OopStorage::allocate() {
MutexLocker ml(_allocation_mutex, Mutex::_no_safepoint_check_flag);
- // Note: Without this we might never perform cleanup. As it is,
- // cleanup is only requested here, when completing a concurrent
- // iteration, or when someone entirely else wakes up the service
- // thread, which isn't ideal. But we can't notify in release().
- if (reduce_deferred_updates()) {
- notify_needs_cleanup();
- }
-
Block* block = block_for_allocation();
if (block == NULL) return NULL; // Block allocation failed.
assert(!block->is_full(), "invariant");
@@ -474,23 +467,20 @@
OopStorage::Block* OopStorage::block_for_allocation() {
assert_lock_strong(_allocation_mutex);
-
while (true) {
// Use the first block in _allocation_list for the allocation.
Block* block = _allocation_list.head();
if (block != NULL) {
return block;
} else if (reduce_deferred_updates()) {
- MutexUnlocker ul(_allocation_mutex, Mutex::_no_safepoint_check_flag);
- notify_needs_cleanup();
+ // Might have added a block to the _allocation_list, so retry.
} else if (try_add_block()) {
- block = _allocation_list.head();
- assert(block != NULL, "invariant");
- return block;
- } else if (reduce_deferred_updates()) { // Once more before failure.
- MutexUnlocker ul(_allocation_mutex, Mutex::_no_safepoint_check_flag);
- notify_needs_cleanup();
- } else {
+ // Successfully added a new block to the list, so retry.
+ assert(_allocation_list.chead() != NULL, "invariant");
+ } else if (_allocation_list.chead() != NULL) {
+ // Trying to add a block failed, but some other thread added to the
+ // list while we'd dropped the lock over the new block allocation.
+ } else if (!reduce_deferred_updates()) { // Once more before failure.
// Attempt to add a block failed, no other thread added a block,
// and no deferred updated added a block, then allocation failed.
log_debug(oopstorage, blocks)("%s: failed block allocation", name());
@@ -635,7 +625,14 @@
if (fetched == head) break; // Successful update.
head = fetched; // Retry with updated head.
}
- owner->record_needs_cleanup();
+ // Only request cleanup for to-empty transitions, not for from-full.
+ // There isn't any rush to process from-full transitions. Allocation
+ // will reduce deferrals before allocating new blocks, so may process
+ // some. And the service thread will drain the entire deferred list
+ // if there are any pending to-empty transitions.
+ if (releasing == old_allocated) {
+ owner->record_needs_cleanup();
+ }
log_debug(oopstorage, blocks)("%s: deferred update " PTR_FORMAT,
_owner->name(), p2i(this));
}
@@ -684,7 +681,6 @@
if (is_empty_bitmask(allocated)) {
_allocation_list.unlink(*block);
_allocation_list.push_back(*block);
- notify_needs_cleanup();
}
log_debug(oopstorage, blocks)("%s: processed deferred update " PTR_FORMAT,
@@ -734,23 +730,12 @@
}
}
-const char* dup_name(const char* name) {
- char* dup = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtGC);
- strcpy(dup, name);
- return dup;
-}
-
-// Possible values for OopStorage::_needs_cleanup.
-const uint needs_cleanup_none = 0; // No cleanup needed.
-const uint needs_cleanup_marked = 1; // Requested, but no notification made.
-const uint needs_cleanup_notified = 2; // Requested and Service thread notified.
-
const size_t initial_active_array_size = 8;
OopStorage::OopStorage(const char* name,
Mutex* allocation_mutex,
Mutex* active_mutex) :
- _name(dup_name(name)),
+ _name(os::strdup(name)),
_active_array(ActiveArray::create(initial_active_array_size)),
_allocation_list(),
_deferred_updates(NULL),
@@ -758,7 +743,7 @@
_active_mutex(active_mutex),
_allocation_count(0),
_concurrent_iteration_count(0),
- _needs_cleanup(needs_cleanup_none)
+ _needs_cleanup(false)
{
_active_array->increment_refcount();
assert(_active_mutex->rank() < _allocation_mutex->rank(),
@@ -793,43 +778,92 @@
Block::delete_block(*block);
}
ActiveArray::destroy(_active_array);
- FREE_C_HEAP_ARRAY(char, _name);
+ os::free(const_cast<char*>(_name));
}
-// Called by service thread to check for pending work.
-bool OopStorage::needs_delete_empty_blocks() const {
- return Atomic::load(&_needs_cleanup) != needs_cleanup_none;
+// Managing service thread notifications.
+//
+// We don't want cleanup work to linger indefinitely, but we also don't want
+// to run the service thread too often. We're also very limited in what we
+// can do in a release operation, where cleanup work is created.
+//
+// When a release operation changes a block's state to empty, it records the
+// need for cleanup in both the associated storage object and in the global
+// request state. A safepoint cleanup task notifies the service thread when
+// there may be cleanup work for any storage object, based on the global
+// request state. But that notification is deferred if the service thread
+// has run recently, and we also avoid duplicate notifications. The service
+// thread updates the timestamp and resets the state flags on every iteration.
+
+// Global cleanup request state.
+static volatile bool needs_cleanup_requested = false;
+
+// Flag for avoiding duplicate notifications.
+static bool needs_cleanup_triggered = false;
+
+// Time after which a notification can be made.
+static jlong cleanup_trigger_permit_time = 0;
+
+// Minimum time since last service thread check before notification is
+// permitted. The value of 500ms was an arbitrary choice; frequent, but not
+// too frequent.
+const jlong cleanup_trigger_defer_period = 500 * NANOSECS_PER_MILLISEC;
+
+void OopStorage::trigger_cleanup_if_needed() {
+ MonitorLocker ml(Service_lock, Monitor::_no_safepoint_check_flag);
+ if (Atomic::load(&needs_cleanup_requested) &&
+ !needs_cleanup_triggered &&
+ (os::javaTimeNanos() > cleanup_trigger_permit_time)) {
+ needs_cleanup_triggered = true;
+ ml.notify_all();
+ }
+}
+
+bool OopStorage::has_cleanup_work_and_reset() {
+ assert_lock_strong(Service_lock);
+ cleanup_trigger_permit_time =
+ os::javaTimeNanos() + cleanup_trigger_defer_period;
+ needs_cleanup_triggered = false;
+ // Set the request flag false and return its old value.
+ // Needs to be atomic to avoid dropping a concurrent request.
+ // Can't use Atomic::xchg, which may not support bool.
+ return Atomic::cmpxchg(false, &needs_cleanup_requested, true);
}
// Record that cleanup is needed, without notifying the Service thread.
// Used by release(), where we can't lock even Service_lock.
void OopStorage::record_needs_cleanup() {
- Atomic::cmpxchg(needs_cleanup_marked, &_needs_cleanup, needs_cleanup_none);
-}
-
-// Record that cleanup is needed, and notify the Service thread.
-void OopStorage::notify_needs_cleanup() {
- // Avoid re-notification if already notified.
- const uint notified = needs_cleanup_notified;
- if (Atomic::xchg(notified, &_needs_cleanup) != notified) {
- MonitorLocker ml(Service_lock, Monitor::_no_safepoint_check_flag);
- ml.notify_all();
- }
+ // Set local flag first, else service thread could wake up and miss
+ // the request. This order may instead (rarely) unnecessarily notify.
+ OrderAccess::release_store(&_needs_cleanup, true);
+ OrderAccess::release_store_fence(&needs_cleanup_requested, true);
}
bool OopStorage::delete_empty_blocks() {
+ // Service thread might have oopstorage work, but not for this object.
+ // Check for deferred updates even though that's not a service thread
+ // trigger; since we're here, we might as well process them.
+ if (!OrderAccess::load_acquire(&_needs_cleanup) &&
+ (OrderAccess::load_acquire(&_deferred_updates) == NULL)) {
+ return false;
+ }
+
MutexLocker ml(_allocation_mutex, Mutex::_no_safepoint_check_flag);
// Clear the request before processing.
- Atomic::store(needs_cleanup_none, &_needs_cleanup);
- OrderAccess::fence();
+ OrderAccess::release_store_fence(&_needs_cleanup, false);
// Other threads could be adding to the empty block count or the
// deferred update list while we're working. Set an upper bound on
// how many updates we'll process and blocks we'll try to release,
// so other threads can't cause an unbounded stay in this function.
- size_t limit = block_count();
- if (limit == 0) return false; // Empty storage; nothing at all to do.
+ // We add a bit of slop because the reduce_deferred_updates clause
+ // can cause blocks to be double counted. If there are few blocks
+ // and many of them are deferred and empty, we might hit the limit
+ // and spin the caller without doing very much work. Otherwise,
+ // we don't normally hit the limit anyway, instead running out of
+ // work to do.
+ size_t limit = block_count() + 10;
for (size_t i = 0; i < limit; ++i) {
// Process deferred updates, which might make empty blocks available.
@@ -946,8 +980,8 @@
_storage->relinquish_block_array(_active_array);
update_concurrent_iteration_count(-1);
if (_concurrent) {
- // We may have deferred some work.
- const_cast<OopStorage*>(_storage)->notify_needs_cleanup();
+ // We may have deferred some cleanup work.
+ const_cast<OopStorage*>(_storage)->record_needs_cleanup();
}
}
--- a/src/hotspot/share/gc/shared/oopStorage.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/oopStorage.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -152,18 +152,26 @@
template<bool concurrent, bool is_const> class ParState;
// Service thread cleanup support.
- // Stops deleting if there is an in-progress concurrent iteration.
- // Locks both the _allocation_mutex and the _active_mutex, and may
- // safepoint. Deletion may be throttled, with only some available
- // work performed, in order to allow other Service thread subtasks
- // to run. Returns true if there may be more work to do, false if
- // nothing to do.
+
+ // Called by the service thread to process any pending cleanups for this
+ // storage object. Drains the _deferred_updates list, and deletes empty
+ // blocks. Stops deleting if there is an in-progress concurrent
+ // iteration. Locks both the _allocation_mutex and the _active_mutex, and
+ // may safepoint. Deletion may be throttled, with only some available
+ // work performed, in order to allow other Service thread subtasks to run.
+ // Returns true if there may be more work to do, false if nothing to do.
bool delete_empty_blocks();
- // Service thread cleanup support.
- // Called by the service thread (while holding Service_lock) to test
- // whether a call to delete_empty_blocks should be made.
- bool needs_delete_empty_blocks() const;
+ // Called by safepoint cleanup to notify the service thread (via
+ // Service_lock) that there may be some OopStorage objects with pending
+ // cleanups to process.
+ static void trigger_cleanup_if_needed();
+
+ // Called by the service thread (while holding Service_lock) to to test
+ // for pending cleanup requests, and resets the request state to allow
+ // recognition of new requests. Returns true if there was a pending
+ // request.
+ static bool has_cleanup_work_and_reset();
// Debugging and logging support.
const char* name() const;
@@ -232,7 +240,7 @@
// mutable because this gets set even for const iteration.
mutable int _concurrent_iteration_count;
- volatile uint _needs_cleanup;
+ volatile bool _needs_cleanup;
bool try_add_block();
Block* block_for_allocation();
@@ -240,7 +248,6 @@
Block* find_block_or_null(const oop* ptr) const;
void delete_empty_block(const Block& block);
bool reduce_deferred_updates();
- void notify_needs_cleanup();
AIX_ONLY(public:) // xlC 12 on AIX doesn't implement C++ DR45.
void record_needs_cleanup();
AIX_ONLY(private:)
--- a/src/hotspot/share/gc/shared/ptrQueue.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shared/ptrQueue.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -296,6 +296,10 @@
class PtrQueueSet {
BufferNode::Allocator* _allocator;
+ // Noncopyable - not defined.
+ PtrQueueSet(const PtrQueueSet&);
+ PtrQueueSet& operator=(const PtrQueueSet&);
+
protected:
bool _all_active;
@@ -309,6 +313,9 @@
public:
+ // Return the associated BufferNode allocator.
+ BufferNode::Allocator* allocator() const { return _allocator; }
+
// Return the buffer for a BufferNode of size buffer_size().
void** allocate_buffer();
--- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -27,6 +27,7 @@
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
+#include "gc/shenandoah/shenandoahRuntime.hpp"
#include "gc/shenandoah/shenandoahThreadLocalData.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
@@ -100,15 +101,15 @@
__ branch_destination(slow->continuation());
}
-LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
+LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj) {
if (ShenandoahLoadRefBarrier) {
- return load_reference_barrier_impl(gen, obj, info, need_null_check);
+ return load_reference_barrier_impl(gen, obj);
} else {
return obj;
}
}
-LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
+LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj) {
assert(ShenandoahLoadRefBarrier, "Should be enabled");
obj = ensure_in_register(gen, obj);
@@ -139,7 +140,7 @@
}
__ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
- CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result, info ? new CodeEmitInfo(info) : NULL, need_null_check);
+ CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result);
__ branch(lir_cond_notEqual, T_INT, slow);
__ branch_destination(slow->continuation());
@@ -183,19 +184,33 @@
return;
}
- LIRGenerator *gen = access.gen();
+ LIRGenerator* gen = access.gen();
+
+ DecoratorSet decorators = access.decorators();
+ if ((decorators & IN_NATIVE) != 0) {
+ assert(access.is_oop(), "IN_NATIVE access only for oop values");
+ BarrierSetC1::load_at_resolved(access, result);
+ LIR_OprList* args = new LIR_OprList();
+ args->append(result);
+ BasicTypeList signature;
+ signature.append(T_OBJECT);
+ LIR_Opr call_result = gen->call_runtime(&signature, args,
+ CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native),
+ objectType, NULL);
+ __ move(call_result, result);
+ return;
+ }
if (ShenandoahLoadRefBarrier) {
LIR_Opr tmp = gen->new_register(T_OBJECT);
BarrierSetC1::load_at_resolved(access, tmp);
- tmp = load_reference_barrier(access.gen(), tmp, access.access_emit_info(), true);
+ tmp = load_reference_barrier(access.gen(), tmp);
__ move(tmp, result);
} else {
BarrierSetC1::load_at_resolved(access, result);
}
if (ShenandoahKeepAliveBarrier) {
- DecoratorSet decorators = access.decorators();
bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
@@ -229,3 +244,10 @@
"shenandoah_pre_barrier_slow",
false, &pre_code_gen_cl);
}
+
+const char* ShenandoahBarrierSetC1::rtcall_name_for_address(address entry) {
+ if (entry == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)) {
+ return "ShenandoahRuntime::load_reference_barrier_native";
+ }
+ return NULL;
+}
--- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -90,12 +90,10 @@
private:
LIR_Opr _obj;
LIR_Opr _result;
- CodeEmitInfo* _info;
- bool _needs_null_check;
public:
- ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr result, CodeEmitInfo* info, bool needs_null_check) :
- _obj(obj), _result(result), _info(info), _needs_null_check(needs_null_check)
+ ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr result) :
+ _obj(obj), _result(result)
{
assert(_obj->is_register(), "should be register");
assert(_result->is_register(), "should be register");
@@ -103,8 +101,6 @@
LIR_Opr obj() const { return _obj; }
LIR_Opr result() const { return _result; }
- CodeEmitInfo* info() const { return _info; }
- bool needs_null_check() const { return _needs_null_check; }
virtual void emit_code(LIR_Assembler* e);
virtual void visit(LIR_OpVisitState* visitor) {
@@ -181,10 +177,10 @@
void pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val);
- LIR_Opr load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check);
+ LIR_Opr load_reference_barrier(LIRGenerator* gen, LIR_Opr obj);
LIR_Opr storeval_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, DecoratorSet decorators);
- LIR_Opr load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check);
+ LIR_Opr load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj);
LIR_Opr ensure_in_register(LIRGenerator* gen, LIR_Opr obj);
@@ -203,6 +199,7 @@
public:
virtual void generate_c1_runtime_stubs(BufferBlob* buffer_blob);
+ virtual const char* rtcall_name_for_address(address entry);
};
#endif // SHARE_GC_SHENANDOAH_C1_SHENANDOAHBARRIERSETC1_HPP
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -297,7 +297,7 @@
bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) {
return call->is_CallLeaf() &&
- call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT);
+ call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier);
}
bool ShenandoahBarrierSetC2::is_shenandoah_marking_if(PhaseTransform *phase, Node* n) {
@@ -544,7 +544,7 @@
if (access.is_oop()) {
if (ShenandoahLoadRefBarrier) {
- load = new ShenandoahLoadReferenceBarrierNode(NULL, load);
+ load = new ShenandoahLoadReferenceBarrierNode(NULL, load, (decorators & IN_NATIVE) != 0);
if (access.is_parse_access()) {
load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
} else {
@@ -629,7 +629,7 @@
load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type()));
}
#endif
- load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store));
+ load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, false));
return load_store;
}
return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type);
@@ -697,7 +697,7 @@
}
Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type);
if (access.is_oop()) {
- result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result));
+ result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, false));
shenandoah_write_barrier_pre(kit, false /* do_load */,
NULL, NULL, max_juint, NULL, NULL,
result /* pre_val */, T_OBJECT);
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1082,7 +1082,7 @@
phase->register_control(ctrl, loop, in_cset_fast_test_iff);
}
-void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase) {
+void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase) {
IdealLoopTree*loop = phase->get_loop(ctrl);
const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr()->cast_to_nonconst();
@@ -1093,7 +1093,10 @@
mm->set_memory_at(Compile::AliasIdxRaw, raw_mem);
phase->register_new_node(mm, ctrl);
- Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), "shenandoah_load_reference_barrier", TypeRawPtr::BOTTOM);
+ address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)
+ : CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier);
+ const char* name = is_native ? "oop_load_from_native_barrier" : "load_reference_barrier";
+ Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
call->init_req(TypeFunc::Control, ctrl);
call->init_req(TypeFunc::I_O, phase->C->top());
call->init_req(TypeFunc::Memory, mm);
@@ -1556,7 +1559,7 @@
Node* result_mem = NULL;
ctrl = if_not_fwd;
fwd = new_val;
- call_lrb_stub(ctrl, fwd, result_mem, raw_mem, phase);
+ call_lrb_stub(ctrl, fwd, result_mem, raw_mem, lrb->is_native(), phase);
region->init_req(_evac_path, ctrl);
val_phi->init_req(_evac_path, fwd);
raw_mem_phi->init_req(_evac_path, result_mem);
@@ -2999,11 +3002,28 @@
}
}
-ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj)
-: Node(ctrl, obj) {
+ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, bool native)
+: Node(ctrl, obj), _native(native) {
ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this);
}
+bool ShenandoahLoadReferenceBarrierNode::is_native() const {
+ return _native;
+}
+
+uint ShenandoahLoadReferenceBarrierNode::size_of() const {
+ return sizeof(*this);
+}
+
+uint ShenandoahLoadReferenceBarrierNode::hash() const {
+ return Node::hash() + (_native ? 1 : 0);
+}
+
+bool ShenandoahLoadReferenceBarrierNode::cmp( const Node &n ) const {
+ return Node::cmp(n) && n.Opcode() == Op_ShenandoahLoadReferenceBarrier &&
+ _native == ((const ShenandoahLoadReferenceBarrierNode&)n)._native;
+}
+
const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const {
if (in(ValueIn) == NULL || in(ValueIn)->is_top()) {
return Type::TOP;
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -60,7 +60,7 @@
static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
static void test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
PhaseIdealLoop* phase);
- static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase);
+ static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase);
static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
PhaseIdealLoop* phase);
@@ -234,8 +234,13 @@
NONE, WEAK, STRONG, NA
};
- ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val);
+private:
+ bool _native;
+public:
+ ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, bool native);
+
+ bool is_native() const;
virtual int Opcode() const;
virtual const Type* bottom_type() const;
virtual const Type* Value(PhaseGVN* phase) const;
@@ -247,9 +252,9 @@
virtual Node* Identity(PhaseGVN* phase);
- uint size_of() const {
- return sizeof(*this);
- }
+ virtual uint size_of() const;
+ virtual uint hash() const;
+ virtual bool cmp( const Node &n ) const;
Strength get_barrier_strength();
CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn);
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -35,18 +35,7 @@
ShenandoahHeuristics(),
_cycle_gap_history(new TruncatedSeq(5)),
_conc_mark_duration_history(new TruncatedSeq(5)),
- _conc_uprefs_duration_history(new TruncatedSeq(5)) {
-
- SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent);
- SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent);
-
- // Final configuration checks
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
-}
+ _conc_uprefs_duration_history(new TruncatedSeq(5)) {}
ShenandoahAdaptiveHeuristics::~ShenandoahAdaptiveHeuristics() {}
@@ -121,7 +110,7 @@
} // Else ignore
}
-bool ShenandoahAdaptiveHeuristics::should_start_normal_gc() const {
+bool ShenandoahAdaptiveHeuristics::should_start_gc() const {
ShenandoahHeap* heap = ShenandoahHeap::heap();
size_t capacity = heap->max_capacity();
size_t available = heap->free_set()->available();
@@ -172,7 +161,7 @@
return true;
}
- return ShenandoahHeuristics::should_start_normal_gc();
+ return ShenandoahHeuristics::should_start_gc();
}
bool ShenandoahAdaptiveHeuristics::should_start_update_refs() {
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -47,7 +47,7 @@
virtual void record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs);
- virtual bool should_start_normal_gc() const;
+ virtual bool should_start_gc() const;
virtual bool should_start_update_refs();
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -65,7 +65,7 @@
}
}
-bool ShenandoahAggressiveHeuristics::should_start_normal_gc() const {
+bool ShenandoahAggressiveHeuristics::should_start_gc() const {
log_info(gc)("Trigger: Start next cycle immediately");
return true;
}
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -34,7 +34,7 @@
RegionData* data, size_t size,
size_t free);
- virtual bool should_start_normal_gc() const;
+ virtual bool should_start_gc() const;
virtual bool should_process_references();
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -49,7 +49,7 @@
SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
}
-bool ShenandoahCompactHeuristics::should_start_normal_gc() const {
+bool ShenandoahCompactHeuristics::should_start_gc() const {
ShenandoahHeap* heap = ShenandoahHeap::heap();
size_t capacity = heap->max_capacity();
@@ -77,7 +77,7 @@
return true;
}
- return ShenandoahHeuristics::should_start_normal_gc();
+ return ShenandoahHeuristics::should_start_gc();
}
void ShenandoahCompactHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -30,7 +30,7 @@
public:
ShenandoahCompactHeuristics();
- virtual bool should_start_normal_gc() const;
+ virtual bool should_start_gc() const;
virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
RegionData* data, size_t size,
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -29,32 +29,7 @@
#include "logging/log.hpp"
#include "logging/logTag.hpp"
-ShenandoahPassiveHeuristics::ShenandoahPassiveHeuristics() : ShenandoahHeuristics() {
- // Do not allow concurrent cycles.
- FLAG_SET_DEFAULT(ExplicitGCInvokesConcurrent, false);
- FLAG_SET_DEFAULT(ShenandoahImplicitGCInvokesConcurrent, false);
-
- // Passive runs with max speed, reacts on allocation failure.
- FLAG_SET_DEFAULT(ShenandoahPacing, false);
-
- // No need for evacuation reserve with Full GC, only for Degenerated GC.
- if (!ShenandoahDegeneratedGC) {
- SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahEvacReserve, 0);
- }
-
- // Disable known barriers by default.
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahLoadRefBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahSATBBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahKeepAliveBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValEnqueueBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier);
-
- // Final configuration checks
- // No barriers are required to run.
-}
-
-bool ShenandoahPassiveHeuristics::should_start_normal_gc() const {
+bool ShenandoahPassiveHeuristics::should_start_gc() const {
// Never do concurrent GCs.
return false;
}
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -28,9 +28,7 @@
class ShenandoahPassiveHeuristics : public ShenandoahHeuristics {
public:
- ShenandoahPassiveHeuristics();
-
- virtual bool should_start_normal_gc() const;
+ virtual bool should_start_gc() const;
virtual bool should_process_references();
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -49,7 +49,7 @@
ShenandoahStaticHeuristics::~ShenandoahStaticHeuristics() {}
-bool ShenandoahStaticHeuristics::should_start_normal_gc() const {
+bool ShenandoahStaticHeuristics::should_start_gc() const {
ShenandoahHeap* heap = ShenandoahHeap::heap();
size_t capacity = heap->max_capacity();
@@ -61,7 +61,7 @@
available / M, threshold_available / M);
return true;
}
- return ShenandoahHeuristics::should_start_normal_gc();
+ return ShenandoahHeuristics::should_start_gc();
}
void ShenandoahStaticHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -32,7 +32,7 @@
virtual ~ShenandoahStaticHeuristics();
- virtual bool should_start_normal_gc() const;
+ virtual bool should_start_gc() const;
virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
RegionData* data, size_t size,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp"
+#include "gc/shenandoah/shenandoahCollectionSet.hpp"
+#include "gc/shenandoah/shenandoahFreeSet.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
+#include "gc/shenandoah/shenandoahHeuristics.hpp"
+#include "gc/shenandoah/shenandoahTraversalGC.hpp"
+#include "logging/log.hpp"
+#include "logging/logTag.hpp"
+#include "utilities/quickSort.hpp"
+
+ShenandoahTraversalAggressiveHeuristics::ShenandoahTraversalAggressiveHeuristics() : ShenandoahHeuristics(),
+ _last_cset_select(0) {
+ // Do not shortcut evacuation
+ SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100);
+
+ // Aggressive runs with max speed for allocation, to capture races against mutator
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing);
+
+ // Aggressive evacuates everything, so it needs as much evac space as it can get
+ SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahEvacReserveOverflow);
+
+ // If class unloading is globally enabled, aggressive does unloading even with
+ // concurrent cycles.
+ if (ClassUnloading) {
+ SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1);
+ }
+
+}
+
+bool ShenandoahTraversalAggressiveHeuristics::is_experimental() {
+ return true;
+}
+
+bool ShenandoahTraversalAggressiveHeuristics::is_diagnostic() {
+ return true;
+}
+
+const char* ShenandoahTraversalAggressiveHeuristics::name() {
+ return "traversal-aggressive";
+}
+
+void ShenandoahTraversalAggressiveHeuristics::choose_collection_set(ShenandoahCollectionSet* collection_set) {
+ ShenandoahHeap* heap = ShenandoahHeap::heap();
+
+ ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
+
+ ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set();
+ traversal_set->clear();
+
+ RegionData *data = get_region_data_cache(heap->num_regions());
+ size_t cnt = 0;
+
+ // Step 0. Prepare all regions
+ for (size_t i = 0; i < heap->num_regions(); i++) {
+ ShenandoahHeapRegion* r = heap->get_region(i);
+ if (r->used() > 0) {
+ if (r->is_regular()) {
+ data[cnt]._region = r;
+ data[cnt]._garbage = r->garbage();
+ data[cnt]._seqnum_last_alloc = r->seqnum_last_alloc_mutator();
+ cnt++;
+ }
+ traversal_set->add_region(r);
+ }
+ }
+
+ for (size_t i = 0; i < cnt; i++) {
+ if (data[i]._seqnum_last_alloc > _last_cset_select) continue;
+
+ ShenandoahHeapRegion* r = data[i]._region;
+ assert (r->is_regular(), "should have been filtered before");
+
+ if (r->garbage() > 0) {
+ assert(!collection_set->is_in(r), "must not yet be in cset");
+ collection_set->add_region(r);
+ }
+ }
+
+ // Clear liveness data
+ // TODO: Merge it with step 0, but save live data in RegionData before.
+ for (size_t i = 0; i < heap->num_regions(); i++) {
+ ShenandoahHeapRegion* r = heap->get_region(i);
+ if (r->used() > 0) {
+ r->clear_live_data();
+ }
+ }
+
+ collection_set->update_region_status();
+
+ _last_cset_select = ShenandoahHeapRegion::seqnum_current_alloc();
+}
+
+void ShenandoahTraversalAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
+ RegionData* data, size_t data_size,
+ size_t free) {
+ ShouldNotReachHere();
+}
+
+bool ShenandoahTraversalAggressiveHeuristics::should_start_gc() const {
+ log_info(gc)("Trigger: Start next cycle immediately");
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALAGGRESSIVEHEURISTICS_HPP
+#define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALAGGRESSIVEHEURISTICS_HPP
+
+#include "gc/shenandoah/shenandoahHeuristics.hpp"
+
+class ShenandoahTraversalAggressiveHeuristics : public ShenandoahHeuristics {
+private:
+ uint64_t _last_cset_select;
+
+protected:
+ virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
+ RegionData* data, size_t data_size,
+ size_t free);
+
+public:
+ ShenandoahTraversalAggressiveHeuristics();
+
+ virtual bool is_experimental();
+
+ virtual bool is_diagnostic();
+
+ virtual const char* name();
+
+ virtual void choose_collection_set(ShenandoahCollectionSet* collection_set);
+ virtual bool should_start_gc() const;
+};
+
+#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALAGGRESSIVEHEURISTICS_HPP
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -34,26 +34,7 @@
#include "utilities/quickSort.hpp"
ShenandoahTraversalHeuristics::ShenandoahTraversalHeuristics() : ShenandoahHeuristics(),
- _last_cset_select(0)
- {
- FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true);
- FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahAllowMixedAllocs, false);
-
- SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent);
- SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent);
-
- // Final configuration checks
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahStoreValEnqueueBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier);
- SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
-}
-
-bool ShenandoahTraversalHeuristics::should_start_normal_gc() const {
- return false;
-}
+ _last_cset_select(0) {}
bool ShenandoahTraversalHeuristics::is_experimental() {
return true;
@@ -63,10 +44,6 @@
return false;
}
-bool ShenandoahTraversalHeuristics::can_do_traversal_gc() {
- return true;
-}
-
const char* ShenandoahTraversalHeuristics::name() {
return "traversal";
}
@@ -202,7 +179,7 @@
_last_cset_select = ShenandoahHeapRegion::seqnum_current_alloc();
}
-bool ShenandoahTraversalHeuristics::should_start_traversal_gc() {
+bool ShenandoahTraversalHeuristics::should_start_gc() const {
ShenandoahHeap* heap = ShenandoahHeap::heap();
assert(!heap->has_forwarded_objects(), "no forwarded objects here");
@@ -251,7 +228,7 @@
log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "M (free) - " SIZE_FORMAT "M (spike) - " SIZE_FORMAT "M (penalties) = " SIZE_FORMAT "M",
available / M, spike_headroom / M, penalties / M, allocation_headroom / M);
return true;
- } else if (ShenandoahHeuristics::should_start_normal_gc()) {
+ } else if (ShenandoahHeuristics::should_start_gc()) {
return true;
}
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -38,19 +38,15 @@
public:
ShenandoahTraversalHeuristics();
- virtual bool should_start_normal_gc() const;
-
virtual bool is_experimental();
virtual bool is_diagnostic();
- virtual bool can_do_traversal_gc();
-
virtual const char* name();
virtual void choose_collection_set(ShenandoahCollectionSet* collection_set);
- virtual bool should_start_traversal_gc();
+ virtual bool should_start_gc() const;
};
#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHTRAVERSALHEURISTICS_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -358,3 +358,16 @@
}
}
}
+
+oop ShenandoahBarrierSet::oop_load_from_native_barrier(oop obj) {
+ if (CompressedOops::is_null(obj)) {
+ return NULL;
+ }
+
+ if (_heap->is_evacuation_in_progress() &&
+ !_heap->complete_marking_context()->is_marked(obj)) {
+ return NULL;
+ }
+
+ return load_reference_barrier_not_null(obj);
+}
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -83,6 +83,8 @@
void write_ref_field_work(void* v, oop o, bool release = false);
void write_region(MemRegion mr);
+ oop oop_load_from_native_barrier(oop obj);
+
virtual void on_thread_create(Thread* thread);
virtual void on_thread_destroy(Thread* thread);
virtual void on_thread_attach(Thread* thread);
@@ -177,6 +179,10 @@
template <typename T>
static oop oop_load_not_in_heap(T* addr);
+ // Used for catching bad stores
+ template <typename T>
+ static void oop_store_not_in_heap(T* addr, oop value);
+
template <typename T>
static oop oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value);
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,6 +25,7 @@
#define SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
#include "gc/shared/barrierSet.hpp"
+#include "gc/shenandoah/shenandoahAsserts.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahForwarding.inline.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
@@ -65,7 +66,7 @@
template <typename T>
inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {
oop value = Raw::oop_load_not_in_heap(addr);
- value = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(value);
+ value = ShenandoahBarrierSet::barrier_set()->oop_load_from_native_barrier(value);
keep_alive_if_weak(decorators, value);
return value;
}
@@ -88,6 +89,13 @@
template <DecoratorSet decorators, typename BarrierSetT>
template <typename T>
+inline void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_store_not_in_heap(T* addr, oop value) {
+ shenandoah_assert_marked_if(NULL, value, !CompressedOops::is_null(value) && ShenandoahHeap::heap()->is_evacuation_in_progress());
+ Raw::oop_store(addr, value);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value) {
oop res;
oop expected = compare_value;
--- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -170,7 +170,7 @@
ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock);
ShenandoahNMethodOopDetector detector;
- nm->oops_do(&detector, /* allow_zombie = */ true);
+ nm->oops_do(&detector, /* allow_dead = */ true);
if (detector.has_oops()) {
int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
--- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -68,6 +68,10 @@
void ShenandoahControlThread::run_service() {
ShenandoahHeap* heap = ShenandoahHeap::heap();
+ GCMode default_mode = heap->is_traversal_mode() ?
+ concurrent_traversal : concurrent_normal;
+ GCCause::Cause default_cause = heap->is_traversal_mode() ?
+ GCCause::_shenandoah_traversal_gc : GCCause::_shenandoah_concurrent_gc;
int sleep = ShenandoahControlIntervalMin;
double last_shrink_time = os::elapsedTime();
@@ -123,11 +127,7 @@
if (ExplicitGCInvokesConcurrent) {
policy->record_explicit_to_concurrent();
- if (heuristics->can_do_traversal_gc()) {
- mode = concurrent_traversal;
- } else {
- mode = concurrent_normal;
- }
+ mode = default_mode;
// Unload and clean up everything
heap->set_process_references(heuristics->can_process_references());
heap->set_unload_classes(heuristics->can_unload_classes());
@@ -143,11 +143,7 @@
if (ShenandoahImplicitGCInvokesConcurrent) {
policy->record_implicit_to_concurrent();
- if (heuristics->can_do_traversal_gc()) {
- mode = concurrent_traversal;
- } else {
- mode = concurrent_normal;
- }
+ mode = default_mode;
// Unload and clean up everything
heap->set_process_references(heuristics->can_process_references());
@@ -158,12 +154,9 @@
}
} else {
// Potential normal cycle: ask heuristics if it wants to act
- if (heuristics->should_start_traversal_gc()) {
- mode = concurrent_traversal;
- cause = GCCause::_shenandoah_traversal_gc;
- } else if (heuristics->should_start_normal_gc()) {
- mode = concurrent_normal;
- cause = GCCause::_shenandoah_concurrent_gc;
+ if (heuristics->should_start_gc()) {
+ mode = default_mode;
+ cause = default_cause;
}
// Ask policy if this cycle wants to process references or unload classes
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -50,23 +50,20 @@
#include "gc/shenandoah/shenandoahMemoryPool.hpp"
#include "gc/shenandoah/shenandoahMetrics.hpp"
#include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
+#include "gc/shenandoah/shenandoahNormalMode.hpp"
#include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
#include "gc/shenandoah/shenandoahPacer.inline.hpp"
+#include "gc/shenandoah/shenandoahPassiveMode.hpp"
#include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
#include "gc/shenandoah/shenandoahStringDedup.hpp"
#include "gc/shenandoah/shenandoahTaskqueue.hpp"
+#include "gc/shenandoah/shenandoahTraversalMode.hpp"
#include "gc/shenandoah/shenandoahUtils.hpp"
#include "gc/shenandoah/shenandoahVerifier.hpp"
#include "gc/shenandoah/shenandoahCodeRoots.hpp"
#include "gc/shenandoah/shenandoahVMOperations.hpp"
#include "gc/shenandoah/shenandoahWorkGroup.hpp"
#include "gc/shenandoah/shenandoahWorkerPolicy.hpp"
-#include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp"
-#include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp"
-#include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp"
-#include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
-#include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
-#include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
#if INCLUDE_JFR
#include "gc/shenandoah/shenandoahJfrSupport.hpp"
#endif
@@ -367,7 +364,7 @@
_pacer = NULL;
}
- _traversal_gc = heuristics()->can_do_traversal_gc() ?
+ _traversal_gc = strcmp(ShenandoahGCMode, "traversal") == 0 ?
new ShenandoahTraversalGC(this, _num_regions) :
NULL;
@@ -387,39 +384,34 @@
}
void ShenandoahHeap::initialize_heuristics() {
- if (ShenandoahGCHeuristics != NULL) {
- if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) {
- _heuristics = new ShenandoahAggressiveHeuristics();
- } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) {
- _heuristics = new ShenandoahStaticHeuristics();
- } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) {
- _heuristics = new ShenandoahAdaptiveHeuristics();
- } else if (strcmp(ShenandoahGCHeuristics, "passive") == 0) {
- _heuristics = new ShenandoahPassiveHeuristics();
- } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) {
- _heuristics = new ShenandoahCompactHeuristics();
- } else if (strcmp(ShenandoahGCHeuristics, "traversal") == 0) {
- _heuristics = new ShenandoahTraversalHeuristics();
+ if (ShenandoahGCMode != NULL) {
+ if (strcmp(ShenandoahGCMode, "traversal") == 0) {
+ _gc_mode = new ShenandoahTraversalMode();
+ } else if (strcmp(ShenandoahGCMode, "normal") == 0) {
+ _gc_mode = new ShenandoahNormalMode();
+ } else if (strcmp(ShenandoahGCMode, "passive") == 0) {
+ _gc_mode = new ShenandoahPassiveMode();
} else {
- vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option");
+ vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option");
}
-
- if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) {
- vm_exit_during_initialization(
- err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.",
- _heuristics->name()));
- }
- if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) {
- vm_exit_during_initialization(
- err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.",
- _heuristics->name()));
- }
- log_info(gc, init)("Shenandoah heuristics: %s",
- _heuristics->name());
} else {
- ShouldNotReachHere();
+ ShouldNotReachHere();
}
-
+ _gc_mode->initialize_flags();
+ _heuristics = _gc_mode->initialize_heuristics();
+
+ if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) {
+ vm_exit_during_initialization(
+ err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.",
+ _heuristics->name()));
+ }
+ if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) {
+ vm_exit_during_initialization(
+ err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.",
+ _heuristics->name()));
+ }
+ log_info(gc, init)("Shenandoah heuristics: %s",
+ _heuristics->name());
}
#ifdef _MSC_VER
@@ -1704,7 +1696,7 @@
set_process_references(heuristics()->can_process_references());
set_unload_classes(heuristics()->can_unload_classes());
- if (heuristics()->can_do_traversal_gc()) {
+ if (is_traversal_mode()) {
// Not possible to degenerate from here, upgrade to Full GC right away.
cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc);
op_degenerated_fail();
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -43,6 +43,7 @@
class ShenandoahGCStateResetter;
class ShenandoahHeuristics;
class ShenandoahMarkingContext;
+class ShenandoahMode;
class ShenandoahPhaseTimings;
class ShenandoahHeap;
class ShenandoahHeapRegion;
@@ -435,6 +436,7 @@
private:
ShenandoahControlThread* _control_thread;
ShenandoahCollectorPolicy* _shenandoah_policy;
+ ShenandoahMode* _gc_mode;
ShenandoahHeuristics* _heuristics;
ShenandoahFreeSet* _free_set;
ShenandoahConcurrentMark* _scm;
@@ -454,7 +456,8 @@
ShenandoahHeuristics* heuristics() const { return _heuristics; }
ShenandoahFreeSet* free_set() const { return _free_set; }
ShenandoahConcurrentMark* concurrent_mark() { return _scm; }
- ShenandoahTraversalGC* traversal_gc() { return _traversal_gc; }
+ ShenandoahTraversalGC* traversal_gc() const { return _traversal_gc; }
+ bool is_traversal_mode() const { return _traversal_gc != NULL; }
ShenandoahPacer* pacer() const { return _pacer; }
ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -228,7 +228,7 @@
return _update_refs_early;
}
-bool ShenandoahHeuristics::should_start_normal_gc() const {
+bool ShenandoahHeuristics::should_start_gc() const {
// Perform GC to cleanup metaspace
if (has_metaspace_oom()) {
// Some of vmTestbase/metaspace tests depend on following line to count GC cycles
@@ -245,14 +245,6 @@
return periodic_gc;
}
-bool ShenandoahHeuristics::should_start_traversal_gc() {
- return false;
-}
-
-bool ShenandoahHeuristics::can_do_traversal_gc() {
- return false;
-}
-
bool ShenandoahHeuristics::should_degenerate_cycle() {
return _degenerated_cycles_in_a_row <= ShenandoahFullGCThreshold;
}
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -127,14 +127,10 @@
virtual void record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs);
- virtual bool should_start_normal_gc() const;
+ virtual bool should_start_gc() const;
virtual bool should_start_update_refs();
- virtual bool should_start_traversal_gc();
-
- virtual bool can_do_traversal_gc();
-
virtual bool should_degenerate_cycle();
virtual void record_success_concurrent();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMode.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP
+
+#include "memory/allocation.hpp"
+
+class ShenandoahHeuristics;
+
+class ShenandoahMode : public CHeapObj<mtGC> {
+public:
+ virtual void initialize_flags() const = 0;
+ virtual ShenandoahHeuristics* initialize_heuristics() const = 0;
+};
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahNormalMode.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahNormalMode.hpp"
+#include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
+#include "logging/log.hpp"
+#include "logging/logTag.hpp"
+
+void ShenandoahNormalMode::initialize_flags() const {
+ SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent);
+ SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent);
+
+ // Final configuration checks
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
+}
+
+ShenandoahHeuristics* ShenandoahNormalMode::initialize_heuristics() const {
+ if (ShenandoahGCHeuristics != NULL) {
+ if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) {
+ return new ShenandoahAggressiveHeuristics();
+ } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) {
+ return new ShenandoahStaticHeuristics();
+ } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) {
+ return new ShenandoahAdaptiveHeuristics();
+ } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) {
+ return new ShenandoahCompactHeuristics();
+ } else {
+ vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option");
+ }
+ }
+ ShouldNotReachHere();
+ return NULL;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahNormalMode.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP
+
+#include "gc/shenandoah/shenandoahMode.hpp"
+
+class ShenandoahHeuristics;
+
+class ShenandoahNormalMode : public ShenandoahMode {
+public:
+ virtual void initialize_flags() const;
+ virtual ShenandoahHeuristics* initialize_heuristics() const;
+};
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahPassiveMode.hpp"
+#include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
+#include "logging/log.hpp"
+#include "logging/logTag.hpp"
+
+void ShenandoahPassiveMode::initialize_flags() const {
+ // Do not allow concurrent cycles.
+ FLAG_SET_DEFAULT(ExplicitGCInvokesConcurrent, false);
+ FLAG_SET_DEFAULT(ShenandoahImplicitGCInvokesConcurrent, false);
+
+ // Passive runs with max speed, reacts on allocation failure.
+ FLAG_SET_DEFAULT(ShenandoahPacing, false);
+
+ // No need for evacuation reserve with Full GC, only for Degenerated GC.
+ if (!ShenandoahDegeneratedGC) {
+ SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahEvacReserve, 0);
+ }
+
+ // Disable known barriers by default.
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahLoadRefBarrier);
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahSATBBarrier);
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahKeepAliveBarrier);
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValEnqueueBarrier);
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier);
+ SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier);
+
+ // Final configuration checks
+ // No barriers are required to run.
+}
+ShenandoahHeuristics* ShenandoahPassiveMode::initialize_heuristics() const {
+ if (ShenandoahGCHeuristics != NULL) {
+ return new ShenandoahPassiveHeuristics();
+ }
+ ShouldNotReachHere();
+ return NULL;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPASSIVEMODE_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHPASSIVEMODE_HPP
+
+#include "gc/shenandoah/shenandoahNormalMode.hpp"
+
+class ShenandoahPassiveMode : public ShenandoahNormalMode {
+public:
+ virtual void initialize_flags() const;
+ virtual ShenandoahHeuristics* initialize_heuristics() const;
+};
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -41,22 +41,27 @@
#include "services/management.hpp"
ShenandoahSerialRoot::ShenandoahSerialRoot(ShenandoahSerialRoot::OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases phase) :
- _claimed(false), _oops_do(oops_do), _phase(phase) {
+ _oops_do(oops_do), _phase(phase) {
}
void ShenandoahSerialRoot::oops_do(OopClosure* cl, uint worker_id) {
- if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
+ if (_claimed.try_set()) {
ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
_oops_do(cl);
}
}
+// Default the second argument for SD::oops_do.
+static void system_dictionary_oops_do(OopClosure* cl) {
+ SystemDictionary::oops_do(cl);
+}
+
ShenandoahSerialRoots::ShenandoahSerialRoots() :
_universe_root(&Universe::oops_do, ShenandoahPhaseTimings::UniverseRoots),
_object_synchronizer_root(&ObjectSynchronizer::oops_do, ShenandoahPhaseTimings::ObjectSynchronizerRoots),
_management_root(&Management::oops_do, ShenandoahPhaseTimings::ManagementRoots),
- _system_dictionary_root(&SystemDictionary::oops_do, ShenandoahPhaseTimings::SystemDictionaryRoots),
+ _system_dictionary_root(&system_dictionary_oops_do, ShenandoahPhaseTimings::SystemDictionaryRoots),
_jvmti_root(&JvmtiExport::oops_do, ShenandoahPhaseTimings::JVMTIRoots) {
}
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -36,7 +36,7 @@
public:
typedef void (*OopsDo)(OopClosure*);
private:
- volatile bool _claimed;
+ ShenandoahSharedFlag _claimed;
const OopsDo _oops_do;
const ShenandoahPhaseTimings::GCParPhases _phase;
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -225,7 +225,7 @@
void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
!ShenandoahHeap::heap()->unload_classes() ||
- ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
+ ShenandoahHeap::heap()->is_traversal_mode(),
"Expect class unloading or traversal when Shenandoah cycle is running");
ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
ResourceMark rm;
--- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -55,7 +55,7 @@
ShenandoahThreadLocalData::satb_mark_queue(thread).enqueue_known_active(orig);
JRT_END
-JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_JRT(oopDesc* src))
+JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier(oopDesc * src))
oop result = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_mutator(src);
return (oopDesc*) result;
JRT_END
@@ -65,3 +65,7 @@
JRT_LEAF(void, ShenandoahRuntime::shenandoah_clone_barrier(oopDesc* obj))
ShenandoahBarrierSet::barrier_set()->write_region(MemRegion((HeapWord*) obj, obj->size()));
JRT_END
+
+JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_native(oopDesc * src))
+ return (oopDesc*) ShenandoahBarrierSet::barrier_set()->oop_load_from_native_barrier(oop(src));
+JRT_END
--- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -37,7 +37,8 @@
static void write_ref_array_post_entry(HeapWord* dst, size_t length);
static void write_ref_field_pre_entry(oopDesc* orig, JavaThread* thread);
- static oopDesc* load_reference_barrier_JRT(oopDesc* src);
+ static oopDesc* load_reference_barrier(oopDesc *src);
+ static oopDesc* load_reference_barrier_native(oopDesc *src);
static void shenandoah_clone_barrier(oopDesc* obj);
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalMode.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahTraversalMode.hpp"
+#include "gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
+#include "logging/log.hpp"
+#include "logging/logTag.hpp"
+
+void ShenandoahTraversalMode::initialize_flags() const {
+ FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true);
+ FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahAllowMixedAllocs, false);
+
+ SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent);
+ SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent);
+
+ // Final configuration checks
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahStoreValEnqueueBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier);
+ SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
+}
+
+ShenandoahHeuristics* ShenandoahTraversalMode::initialize_heuristics() const {
+ if (ShenandoahGCHeuristics != NULL) {
+ if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) {
+ return new ShenandoahTraversalHeuristics();
+ } else if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) {
+ return new ShenandoahTraversalAggressiveHeuristics();
+ } else {
+ vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option");
+ }
+ }
+ ShouldNotReachHere();
+ return NULL;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalMode.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALMODE_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALMODE_HPP
+
+#include "gc/shenandoah/shenandoahMode.hpp"
+
+class ShenandoahHeuristics;
+
+class ShenandoahTraversalMode : public ShenandoahMode {
+public:
+ virtual void initialize_flags() const;
+ virtual ShenandoahHeuristics* initialize_heuristics() const;
+};
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALMODE_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -65,13 +65,18 @@
" *) static - start concurrent GC when static free heap " \
" threshold and static allocation threshold are " \
" tripped;" \
- " *) passive - do not start concurrent GC, wait for Full GC; " \
" *) aggressive - run concurrent GC continuously, evacuate " \
" everything;" \
" *) compact - run GC with lower footprint target, may end up " \
" doing continuous GC, evacuate lots of live " \
" objects, uncommit heap aggressively;") \
\
+ experimental(ccstr, ShenandoahGCMode, "normal", \
+ "The GC mode to use in Shenandoah GC. Possible values" \
+ " *) normal - normal GC (mark-evac-update)" \
+ " *) traversal - traversal GC (single-pass)" \
+ " *) passive - disable concurrent GC, do stop-the-world GC") \
+ \
experimental(ccstr, ShenandoahUpdateRefsEarly, "adaptive", \
"Run a separate concurrent reference updating phase after" \
"concurrent evacuation. Possible values: 'on', 'off', 'adaptive'")\
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -128,14 +128,19 @@
}
}
-static bool load_require_barrier(LoadNode* load) { return ((load->barrier_data() & RequireBarrier) != 0); }
-static bool load_has_weak_barrier(LoadNode* load) { return ((load->barrier_data() & WeakBarrier) != 0); }
-static bool load_has_expanded_barrier(LoadNode* load) { return ((load->barrier_data() & ExpandedBarrier) != 0); }
+const uint NoBarrier = 0;
+const uint RequireBarrier = 1;
+const uint WeakBarrier = 2;
+const uint ExpandedBarrier = 4;
+
+static bool load_require_barrier(LoadNode* load) { return (load->barrier_data() & RequireBarrier) == RequireBarrier; }
+static bool load_has_weak_barrier(LoadNode* load) { return (load->barrier_data() & WeakBarrier) == WeakBarrier; }
+static bool load_has_expanded_barrier(LoadNode* load) { return (load->barrier_data() & ExpandedBarrier) == ExpandedBarrier; }
static void load_set_expanded_barrier(LoadNode* load) { return load->set_barrier_data(ExpandedBarrier); }
-static void load_set_barrier(LoadNode* load, bool weak) {
+static void load_set_barrier(LoadNode* load, bool weak) {
if (weak) {
- load->set_barrier_data(WeakBarrier);
+ load->set_barrier_data(RequireBarrier | WeakBarrier);
} else {
load->set_barrier_data(RequireBarrier);
}
@@ -540,8 +545,8 @@
Node* then = igvn.transform(new IfTrueNode(iff));
Node* elsen = igvn.transform(new IfFalseNode(iff));
- Node* new_loadp = igvn.transform(new LoadBarrierSlowRegNode(then, in_mem, in_adr, in_val->adr_type(),
- (const TypePtr*) in_val->bottom_type(), MemNode::unordered, barrier->is_weak()));
+ Node* new_loadp = igvn.transform(new LoadBarrierSlowRegNode(then, in_adr, in_val,
+ (const TypePtr*) in_val->bottom_type(), barrier->is_weak()));
// Create the final region/phi pair to converge cntl/data paths to downstream code
Node* result_region = igvn.transform(new RegionNode(3));
@@ -667,7 +672,6 @@
case Op_ZCompareAndExchangeP:
case Op_ZCompareAndSwapP:
case Op_ZWeakCompareAndSwapP:
- case Op_LoadBarrierSlowReg:
#ifdef ASSERT
if (VerifyOptoOopOffsets) {
MemNode *mem = n->as_Mem();
@@ -1229,7 +1233,6 @@
Compile *C = phase->C;
PhaseIterGVN &igvn = phase->igvn();
LoadStoreNode* zclone = NULL;
- bool is_weak = false;
Node *in_ctrl = old_node->in(MemNode::Control);
Node *in_mem = old_node->in(MemNode::Memory);
@@ -1249,7 +1252,6 @@
if (can_simplify_cas(old_node)) {
break;
}
- is_weak = true;
zclone = new ZWeakCompareAndSwapPNode(in_ctrl, in_mem, in_adr, in_val, old_node->in(LoadStoreConditionalNode::ExpectedIn),
((CompareAndSwapNode*)old_node)->order());
adr_type = TypePtr::BOTTOM;
@@ -1280,7 +1282,7 @@
igvn.register_new_node_with_optimizer(load);
igvn.replace_node(old_node, zclone);
- Node *barrier = new LoadBarrierNode(C, NULL, in_mem, load, in_adr, is_weak);
+ Node *barrier = new LoadBarrierNode(C, NULL, in_mem, load, in_adr, false /* weak */);
Node *barrier_val = new ProjNode(barrier, LoadBarrierNode::Oop);
Node *barrier_ctrl = new ProjNode(barrier, LoadBarrierNode::Control);
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -104,22 +104,25 @@
}
};
-class LoadBarrierSlowRegNode : public LoadPNode {
+class LoadBarrierSlowRegNode : public TypeNode {
private:
- bool _is_weak;
+ bool _is_weak;
public:
LoadBarrierSlowRegNode(Node *c,
- Node *mem,
Node *adr,
- const TypePtr *at,
+ Node *src,
const TypePtr* t,
- MemOrd mo,
- bool weak = false,
- ControlDependency control_dependency = DependsOnlyOnTest) :
- LoadPNode(c, mem, adr, at, t, mo, control_dependency), _is_weak(weak) {
+ bool weak) :
+ TypeNode(t, 3), _is_weak(weak) {
+ init_req(1, adr);
+ init_req(2, src);
init_class_id(Class_LoadBarrierSlowReg);
}
+ virtual uint size_of() const {
+ return sizeof(*this);
+ }
+
virtual const char * name() {
return "LoadBarrierSlowRegNode";
}
@@ -146,13 +149,6 @@
LoadBarrierNode* load_barrier_node(int idx) const;
};
-enum BarrierInfo {
- NoBarrier = 0,
- RequireBarrier = 1,
- WeakBarrier = 3, // Inclusive with RequireBarrier
- ExpandedBarrier = 4
-};
-
class ZBarrierSetC2 : public BarrierSetC2 {
private:
ZBarrierSetC2State* state() const;
--- a/src/hotspot/share/gc/z/zArguments.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zArguments.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -92,6 +92,11 @@
// same reason we need fixup_partial_loads
FLAG_SET_DEFAULT(VerifyBeforeIteration, false);
+ if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
+ FLAG_SET_DEFAULT(ZVerifyRoots, true);
+ FLAG_SET_DEFAULT(ZVerifyObjects, true);
+ }
+
// Verification of stacks not (yet) supported, for the same reason
// we need fixup_partial_loads
DEBUG_ONLY(FLAG_SET_DEFAULT(VerifyStack, false));
--- a/src/hotspot/share/gc/z/zBarrier.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -24,10 +24,12 @@
#ifndef SHARE_GC_Z_ZBARRIER_INLINE_HPP
#define SHARE_GC_Z_ZBARRIER_INLINE_HPP
+#include "classfile/javaClasses.hpp"
#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zBarrier.hpp"
#include "gc/z/zOop.inline.hpp"
#include "gc/z/zResurrection.inline.hpp"
+#include "oops/oop.hpp"
#include "runtime/atomic.hpp"
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
@@ -173,7 +175,21 @@
}
}
+// ON_WEAK barriers should only ever be applied to j.l.r.Reference.referents.
+inline void verify_on_weak(volatile oop* referent_addr) {
+#ifdef ASSERT
+ if (referent_addr != NULL) {
+ uintptr_t base = (uintptr_t)referent_addr - java_lang_ref_Reference::referent_offset;
+ oop obj = cast_to_oop(base);
+ assert(oopDesc::is_oop(obj), "Verification failed for: ref " PTR_FORMAT " obj: " PTR_FORMAT, (uintptr_t)referent_addr, base);
+ assert(java_lang_ref_Reference::is_referent_field(obj, java_lang_ref_Reference::referent_offset), "Sanity");
+ }
+#endif
+}
+
inline oop ZBarrier::load_barrier_on_weak_oop_field_preloaded(volatile oop* p, oop o) {
+ verify_on_weak(p);
+
if (is_resurrection_blocked(p, &o)) {
return weak_barrier<is_good_or_null_fast_path, weak_load_barrier_on_weak_oop_slow_path>(p, o);
}
@@ -217,6 +233,8 @@
}
inline oop ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(volatile oop* p, oop o) {
+ verify_on_weak(p);
+
if (is_resurrection_blocked(p, &o)) {
return weak_barrier<is_good_or_null_fast_path, weak_load_barrier_on_weak_oop_slow_path>(p, o);
}
--- a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -62,6 +62,7 @@
} else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {
return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);
} else {
+ assert((HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value), "Must be");
return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);
}
} else {
@@ -70,6 +71,7 @@
} else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {
return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);
} else {
+ assert((HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value), "Must be");
return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);
}
}
@@ -89,6 +91,7 @@
} else if (decorators_known_strength & ON_WEAK_OOP_REF) {
return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);
} else {
+ assert(decorators_known_strength & ON_PHANTOM_OOP_REF, "Must be");
return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);
}
} else {
@@ -97,6 +100,7 @@
} else if (decorators_known_strength & ON_WEAK_OOP_REF) {
return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);
} else {
+ assert(decorators_known_strength & ON_PHANTOM_OOP_REF, "Must be");
return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);
}
}
--- a/src/hotspot/share/gc/z/zCollectedHeap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -232,11 +232,11 @@
}
void ZCollectedHeap::object_iterate(ObjectClosure* cl) {
- _heap.object_iterate(cl, true /* visit_referents */);
+ _heap.object_iterate(cl, true /* visit_weaks */);
}
void ZCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
- _heap.object_iterate(cl, true /* visit_referents */);
+ _heap.object_iterate(cl, true /* visit_weaks */);
}
HeapWord* ZCollectedHeap::block_start(const void* addr) const {
--- a/src/hotspot/share/gc/z/zDriver.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zDriver.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -31,6 +31,7 @@
#include "gc/z/zMessagePort.inline.hpp"
#include "gc/z/zServiceability.hpp"
#include "gc/z/zStat.hpp"
+#include "gc/z/zVerify.hpp"
#include "logging/log.hpp"
#include "memory/universe.hpp"
#include "runtime/vmOperations.hpp"
@@ -86,6 +87,9 @@
GCIdMark gc_id_mark(_gc_id);
IsGCActiveMark gc_active_mark;
+ // Verify roots
+ ZVerify::roots_strong();
+
// Execute operation
_success = do_operation();
@@ -301,8 +305,14 @@
void ZDriver::pause_verify() {
if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
+ // Full verification
VM_Verify op;
VMThread::execute(&op);
+
+ } else if (ZVerifyRoots || ZVerifyObjects) {
+ // Limited verification
+ VM_ZVerifyOperation op;
+ VMThread::execute(&op);
}
}
--- a/src/hotspot/share/gc/z/zHeap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zHeap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -41,6 +41,7 @@
#include "gc/z/zTask.hpp"
#include "gc/z/zThread.hpp"
#include "gc/z/zTracer.inline.hpp"
+#include "gc/z/zVerify.hpp"
#include "gc/z/zVirtualMemory.inline.hpp"
#include "gc/z/zWorkers.inline.hpp"
#include "logging/log.hpp"
@@ -340,6 +341,9 @@
// Enter mark completed phase
ZGlobalPhase = ZPhaseMarkCompleted;
+ // Verify after mark
+ ZVerify::after_mark();
+
// Update statistics
ZStatSample(ZSamplerHeapUsedAfterMark, used());
ZStatHeap::set_at_mark_end(capacity(), allocated(), used());
@@ -468,11 +472,11 @@
used(), used_high(), used_low());
}
-void ZHeap::object_iterate(ObjectClosure* cl, bool visit_referents) {
+void ZHeap::object_iterate(ObjectClosure* cl, bool visit_weaks) {
assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
ZHeapIterator iter;
- iter.objects_do(cl, visit_referents);
+ iter.objects_do(cl, visit_weaks);
}
void ZHeap::serviceability_initialize() {
@@ -518,40 +522,11 @@
st->cr();
}
-class ZVerifyRootsTask : public ZTask {
-private:
- ZStatTimerDisable _disable;
- ZRootsIterator _strong_roots;
- ZWeakRootsIterator _weak_roots;
-
-public:
- ZVerifyRootsTask() :
- ZTask("ZVerifyRootsTask"),
- _disable(),
- _strong_roots(),
- _weak_roots() {}
-
- virtual void work() {
- ZStatTimerDisable disable;
- ZVerifyOopClosure cl;
- _strong_roots.oops_do(&cl);
- _weak_roots.oops_do(&cl);
- }
-};
-
void ZHeap::verify() {
// Heap verification can only be done between mark end and
// relocate start. This is the only window where all oop are
// good and the whole heap is in a consistent state.
guarantee(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
- {
- ZVerifyRootsTask task;
- _workers.run_parallel(&task);
- }
-
- {
- ZVerifyObjectClosure cl;
- object_iterate(&cl, false /* visit_referents */);
- }
+ ZVerify::after_weak_processing();
}
--- a/src/hotspot/share/gc/z/zHeap.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zHeap.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -161,7 +161,7 @@
void relocate();
// Iteration
- void object_iterate(ObjectClosure* cl, bool visit_referents);
+ void object_iterate(ObjectClosure* cl, bool visit_weaks);
// Serviceability
void serviceability_initialize();
--- a/src/hotspot/share/gc/z/zHeapIterator.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zHeapIterator.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -22,6 +22,8 @@
*/
#include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderDataGraph.hpp"
#include "gc/z/zBarrier.inline.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zGranuleMap.inline.hpp"
@@ -83,7 +85,7 @@
};
template <bool VisitReferents>
-class ZHeapIteratorOopClosure : public BasicOopIterateClosure {
+class ZHeapIteratorOopClosure : public ClaimMetadataVisitingOopIterateClosure {
private:
ZHeapIterator* const _iter;
const oop _base;
@@ -98,6 +100,7 @@
public:
ZHeapIteratorOopClosure(ZHeapIterator* iter, oop base) :
+ ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_other),
_iter(iter),
_base(base) {}
@@ -130,6 +133,7 @@
for (ZHeapIteratorBitMap* map; iter.next(&map);) {
delete map;
}
+ ClassLoaderDataGraph::clear_claimed_marks(ClassLoaderData::_claim_other);
}
static size_t object_index_max() {
@@ -184,15 +188,23 @@
obj->oop_iterate(&cl);
}
-template <bool VisitReferents>
+class ZHeapIterateConcurrentRootsIterator : public ZConcurrentRootsIterator {
+public:
+ ZHeapIterateConcurrentRootsIterator() :
+ ZConcurrentRootsIterator(ClassLoaderData::_claim_other) {}
+};
+
+template <bool VisitWeaks>
void ZHeapIterator::objects_do(ObjectClosure* cl) {
ZStatTimerDisable disable;
// Push roots to visit
- push_roots<ZRootsIterator, false /* Concurrent */, false /* Weak */>();
- push_roots<ZConcurrentRootsIterator, true /* Concurrent */, false /* Weak */>();
- push_roots<ZWeakRootsIterator, false /* Concurrent */, true /* Weak */>();
- push_roots<ZConcurrentWeakRootsIterator, true /* Concurrent */, true /* Weak */>();
+ push_roots<ZRootsIterator, false /* Concurrent */, false /* Weak */>();
+ push_roots<ZHeapIterateConcurrentRootsIterator, true /* Concurrent */, false /* Weak */>();
+ if (VisitWeaks) {
+ push_roots<ZWeakRootsIterator, false /* Concurrent */, true /* Weak */>();
+ push_roots<ZConcurrentWeakRootsIterator, true /* Concurrent */, true /* Weak */>();
+ }
// Drain stack
while (!_visit_stack.is_empty()) {
@@ -202,14 +214,14 @@
cl->do_object(obj);
// Push fields to visit
- push_fields<VisitReferents>(obj);
+ push_fields<VisitWeaks>(obj);
}
}
-void ZHeapIterator::objects_do(ObjectClosure* cl, bool visit_referents) {
- if (visit_referents) {
- objects_do<true /* VisitReferents */>(cl);
+void ZHeapIterator::objects_do(ObjectClosure* cl, bool visit_weaks) {
+ if (visit_weaks) {
+ objects_do<true /* VisitWeaks */>(cl);
} else {
- objects_do<false /* VisitReferents */>(cl);
+ objects_do<false /* VisitWeaks */>(cl);
}
}
--- a/src/hotspot/share/gc/z/zHeapIterator.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zHeapIterator.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -54,7 +54,7 @@
ZHeapIterator();
~ZHeapIterator();
- void objects_do(ObjectClosure* cl, bool visit_referents);
+ void objects_do(ObjectClosure* cl, bool visit_weaks);
};
#endif // SHARE_GC_Z_ZHEAPITERATOR_HPP
--- a/src/hotspot/share/gc/z/zMark.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zMark.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/classLoaderDataGraph.hpp"
#include "gc/z/zBarrier.inline.hpp"
#include "gc/z/zMark.inline.hpp"
#include "gc/z/zMarkCache.inline.hpp"
@@ -632,14 +633,23 @@
class ZMarkConcurrentRootsTask : public ZTask {
private:
+ SuspendibleThreadSetJoiner _sts_joiner;
ZConcurrentRootsIterator _roots;
ZMarkConcurrentRootsIteratorClosure _cl;
public:
ZMarkConcurrentRootsTask(ZMark* mark) :
ZTask("ZMarkConcurrentRootsTask"),
- _roots(true /* marking */),
- _cl() {}
+ _sts_joiner(true /* active */),
+ _roots(ClassLoaderData::_claim_strong),
+ _cl() {
+ ClassLoaderDataGraph_lock->lock();
+ ClassLoaderDataGraph::clear_claimed_marks();
+ }
+
+ ~ZMarkConcurrentRootsTask() {
+ ClassLoaderDataGraph_lock->unlock();
+ }
virtual void work() {
_roots.oops_do(&_cl);
--- a/src/hotspot/share/gc/z/zOopClosures.cpp Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zHeap.hpp"
-#include "gc/z/zOopClosures.inline.hpp"
-#include "gc/z/zOop.inline.hpp"
-#include "memory/iterator.inline.hpp"
-#include "oops/access.inline.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/safepoint.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-void ZVerifyOopClosure::do_oop(oop* p) {
- guarantee(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
- guarantee(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
- guarantee(!ZResurrection::is_blocked(), "Invalid phase");
-
- const oop o = RawAccess<>::oop_load(p);
- if (o != NULL) {
- const uintptr_t addr = ZOop::to_address(o);
- const uintptr_t good_addr = ZAddress::good(addr);
- guarantee(ZAddress::is_good(addr) || ZAddress::is_finalizable_good(addr),
- "Bad oop " PTR_FORMAT " found at " PTR_FORMAT ", expected " PTR_FORMAT,
- addr, p2i(p), good_addr);
- guarantee(oopDesc::is_oop(ZOop::from_address(good_addr)),
- "Bad object " PTR_FORMAT " found at " PTR_FORMAT,
- addr, p2i(p));
- }
-}
-
-void ZVerifyOopClosure::do_oop(narrowOop* p) {
- ShouldNotReachHere();
-}
-
-void ZVerifyObjectClosure::do_object(oop o) {
- ZVerifyOopClosure cl;
- o->oop_iterate(&cl);
-}
--- a/src/hotspot/share/gc/z/zOopClosures.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zOopClosures.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,16 +46,13 @@
};
template <bool finalizable>
-class ZMarkBarrierOopClosure : public MetadataVisitingOopIterateClosure {
+class ZMarkBarrierOopClosure : public ClaimMetadataVisitingOopIterateClosure {
public:
ZMarkBarrierOopClosure();
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
- virtual void do_klass(Klass* k);
- virtual void do_cld(ClassLoaderData* cld);
-
#ifdef ASSERT
virtual bool should_verify_oops() {
return false;
@@ -80,26 +77,4 @@
virtual void do_oop(narrowOop* p);
};
-class ZVerifyOopClosure : public ZRootsIteratorClosure, public BasicOopIterateClosure {
-public:
- virtual void do_oop(oop* p);
- virtual void do_oop(narrowOop* p);
-
- virtual ReferenceIterationMode reference_iteration_mode() {
- return DO_FIELDS;
- }
-
-#ifdef ASSERT
- // Verification handled by the closure itself
- virtual bool should_verify_oops() {
- return false;
- }
-#endif
-};
-
-class ZVerifyObjectClosure : public ObjectClosure {
-public:
- virtual void do_object(oop o);
-};
-
#endif // SHARE_GC_Z_ZOOPCLOSURES_HPP
--- a/src/hotspot/share/gc/z/zOopClosures.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zOopClosures.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,12 @@
template <bool finalizable>
inline ZMarkBarrierOopClosure<finalizable>::ZMarkBarrierOopClosure() :
- MetadataVisitingOopIterateClosure(finalizable ? NULL : ZHeap::heap()->reference_discoverer()) {}
+ ClaimMetadataVisitingOopIterateClosure(finalizable
+ ? ClassLoaderData::_claim_finalizable
+ : ClassLoaderData::_claim_strong,
+ finalizable
+ ? NULL
+ : ZHeap::heap()->reference_discoverer()) {}
template <bool finalizable>
inline void ZMarkBarrierOopClosure<finalizable>::do_oop(oop* p) {
@@ -67,18 +72,6 @@
ShouldNotReachHere();
}
-template <bool finalizable>
-inline void ZMarkBarrierOopClosure<finalizable>::do_klass(Klass* k) {
- ClassLoaderData* const cld = k->class_loader_data();
- ZMarkBarrierOopClosure<finalizable>::do_cld(cld);
-}
-
-template <bool finalizable>
-inline void ZMarkBarrierOopClosure<finalizable>::do_cld(ClassLoaderData* cld) {
- const int claim = finalizable ? ClassLoaderData::_claim_finalizable : ClassLoaderData::_claim_strong;
- cld->oops_do(this, claim);
-}
-
inline bool ZPhantomIsAliveObjectClosure::do_object_b(oop o) {
return ZBarrier::is_alive_barrier_on_phantom_oop(o);
}
--- a/src/hotspot/share/gc/z/zRootsIterator.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zRootsIterator.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -69,6 +69,7 @@
static const ZStatSubPhase ZSubPhaseConcurrentRoots("Concurrent Roots");
static const ZStatSubPhase ZSubPhaseConcurrentRootsTeardown("Concurrent Roots Teardown");
static const ZStatSubPhase ZSubPhaseConcurrentRootsJNIHandles("Concurrent Roots JNIHandles");
+static const ZStatSubPhase ZSubPhaseConcurrentRootsVMHandles("Concurrent Roots VMHandles");
static const ZStatSubPhase ZSubPhaseConcurrentRootsClassLoaderDataGraph("Concurrent Roots ClassLoaderDataGraph");
static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup");
@@ -231,7 +232,8 @@
void ZRootsIterator::do_system_dictionary(ZRootsIteratorClosure* cl) {
ZStatTimer timer(ZSubPhasePauseRootsSystemDictionary);
- SystemDictionary::oops_do(cl);
+ // Handles are processed via _vm_handles.
+ SystemDictionary::oops_do(cl, false /* include_handles */);
}
void ZRootsIterator::do_threads(ZRootsIteratorClosure* cl) {
@@ -262,24 +264,18 @@
}
}
-ZConcurrentRootsIterator::ZConcurrentRootsIterator(bool marking) :
- _marking(marking),
- _sts_joiner(marking /* active */),
+ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) :
_jni_handles_iter(JNIHandles::global_handles()),
+ _vm_handles_iter(SystemDictionary::vm_global_oop_storage()),
+ _cld_claim(cld_claim),
_jni_handles(this),
+ _vm_handles(this),
_class_loader_data_graph(this) {
ZStatTimer timer(ZSubPhaseConcurrentRootsSetup);
- if (_marking) {
- ClassLoaderDataGraph_lock->lock();
- ClassLoaderDataGraph::clear_claimed_marks();
- }
}
ZConcurrentRootsIterator::~ZConcurrentRootsIterator() {
ZStatTimer timer(ZSubPhaseConcurrentRootsTeardown);
- if (_marking) {
- ClassLoaderDataGraph_lock->unlock();
- }
}
void ZConcurrentRootsIterator::do_jni_handles(ZRootsIteratorClosure* cl) {
@@ -287,20 +283,21 @@
_jni_handles_iter.oops_do(cl);
}
+void ZConcurrentRootsIterator::do_vm_handles(ZRootsIteratorClosure* cl) {
+ ZStatTimer timer(ZSubPhaseConcurrentRootsVMHandles);
+ _vm_handles_iter.oops_do(cl);
+}
+
void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) {
ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph);
- if (_marking) {
- CLDToOopClosure cld_cl(cl, ClassLoaderData::_claim_strong);
- ClassLoaderDataGraph::always_strong_cld_do(&cld_cl);
- } else {
- CLDToOopClosure cld_cl(cl, ClassLoaderData::_claim_none);
- ClassLoaderDataGraph::cld_do(&cld_cl);
- }
+ CLDToOopClosure cld_cl(cl, _cld_claim);
+ ClassLoaderDataGraph::always_strong_cld_do(&cld_cl);
}
void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
ZStatTimer timer(ZSubPhaseConcurrentRoots);
_jni_handles.oops_do(cl);
+ _vm_handles.oops_do(cl),
_class_loader_data_graph.oops_do(cl);
}
--- a/src/hotspot/share/gc/z/zRootsIterator.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/zRootsIterator.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -111,18 +111,20 @@
class ZConcurrentRootsIterator {
private:
- const bool _marking;
- SuspendibleThreadSetJoiner _sts_joiner;
ZOopStorageIterator _jni_handles_iter;
+ ZOopStorageIterator _vm_handles_iter;
+ int _cld_claim;
void do_jni_handles(ZRootsIteratorClosure* cl);
+ void do_vm_handles(ZRootsIteratorClosure* cl);
void do_class_loader_data_graph(ZRootsIteratorClosure* cl);
ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_jni_handles> _jni_handles;
+ ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_vm_handles> _vm_handles;
ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_class_loader_data_graph> _class_loader_data_graph;
public:
- ZConcurrentRootsIterator(bool marking = false);
+ ZConcurrentRootsIterator(int cld_claim);
~ZConcurrentRootsIterator();
void oops_do(ZRootsIteratorClosure* cl);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zVerify.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderDataGraph.hpp"
+#include "gc/z/zAddress.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zOop.hpp"
+#include "gc/z/zResurrection.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zVerify.hpp"
+#include "memory/allocation.hpp"
+#include "memory/iterator.inline.hpp"
+#include "oops/oop.inline.hpp"
+
+#define BAD_OOP_REPORT(addr) \
+ "Bad oop " PTR_FORMAT " found at " PTR_FORMAT ", expected " PTR_FORMAT, \
+ addr, p2i(p), ZAddress::good(addr)
+
+class ZVerifyRootsClosure : public ZRootsIteratorClosure {
+public:
+ virtual void do_oop(oop* p) {
+ uintptr_t value = ZOop::to_address(*p);
+
+ if (value == 0) {
+ return;
+ }
+
+ guarantee(!ZAddress::is_finalizable(value), BAD_OOP_REPORT(value));
+ guarantee(ZAddress::is_good(value), BAD_OOP_REPORT(value));
+ guarantee(oopDesc::is_oop(ZOop::from_address(value)), BAD_OOP_REPORT(value));
+ }
+ virtual void do_oop(narrowOop*) { ShouldNotReachHere(); }
+};
+
+template <bool VisitReferents>
+class ZVerifyOopClosure : public ClaimMetadataVisitingOopIterateClosure, public ZRootsIteratorClosure {
+public:
+ ZVerifyOopClosure() :
+ ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_other) {}
+
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+
+ virtual ReferenceIterationMode reference_iteration_mode() {
+ return VisitReferents ? DO_FIELDS : DO_FIELDS_EXCEPT_REFERENT;
+ }
+
+#ifdef ASSERT
+ // Verification handled by the closure itself
+ virtual bool should_verify_oops() {
+ return false;
+ }
+#endif
+};
+
+class ZVerifyObjectClosure : public ObjectClosure {
+private:
+ bool _visit_referents;
+
+public:
+ ZVerifyObjectClosure(bool visit_referents) : _visit_referents(visit_referents) {}
+ virtual void do_object(oop o);
+};
+
+template <typename RootsIterator>
+void ZVerify::roots_impl() {
+ if (ZVerifyRoots) {
+ ZVerifyRootsClosure cl;
+ RootsIterator iter;
+ iter.oops_do(&cl);
+ }
+}
+
+void ZVerify::roots_strong() {
+ roots_impl<ZRootsIterator>();
+}
+
+class ZVerifyConcurrentRootsIterator : public ZConcurrentRootsIterator {
+public:
+ ZVerifyConcurrentRootsIterator()
+ : ZConcurrentRootsIterator(ClassLoaderData::_claim_none) {}
+};
+
+void ZVerify::roots_concurrent() {
+ roots_impl<ZVerifyConcurrentRootsIterator>();
+}
+
+void ZVerify::roots_weak() {
+ assert(!ZResurrection::is_blocked(), "Invalid phase");
+
+ roots_impl<ZWeakRootsIterator>();
+}
+
+void ZVerify::roots(bool verify_weaks) {
+ roots_strong();
+ roots_concurrent();
+ if (verify_weaks) {
+ roots_weak();
+ roots_concurrent_weak();
+ }
+}
+
+void ZVerify::objects(bool verify_weaks) {
+ if (ZVerifyObjects) {
+ ZVerifyObjectClosure cl(verify_weaks);
+ ZHeap::heap()->object_iterate(&cl, verify_weaks);
+ }
+}
+
+void ZVerify::roots_concurrent_weak() {
+ assert(!ZResurrection::is_blocked(), "Invalid phase");
+
+ roots_impl<ZConcurrentWeakRootsIterator>();
+}
+
+void ZVerify::roots_and_objects(bool verify_weaks) {
+ ZStatTimerDisable _disable;
+
+ roots(verify_weaks);
+ objects(verify_weaks);
+}
+
+void ZVerify::after_mark() {
+ // Only verify strong roots and references.
+ roots_and_objects(false /* verify_weaks */);
+}
+
+void ZVerify::after_weak_processing() {
+ // Also verify weaks - all should have been processed at this point.
+ roots_and_objects(true /* verify_weaks */);
+}
+
+template <bool VisitReferents>
+void ZVerifyOopClosure<VisitReferents>::do_oop(oop* p) {
+ guarantee(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
+ guarantee(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
+ guarantee(!ZResurrection::is_blocked(), "Invalid phase");
+
+ const oop o = RawAccess<>::oop_load(p);
+ if (o == NULL) {
+ return;
+ }
+
+ const uintptr_t addr = ZOop::to_address(o);
+ if (VisitReferents) {
+ guarantee(ZAddress::is_good(addr) || ZAddress::is_finalizable_good(addr), BAD_OOP_REPORT(addr));
+ } else {
+ // Should not encounter finalizable oops through strong-only paths. Assumes only strong roots are visited.
+ guarantee(ZAddress::is_good(addr), BAD_OOP_REPORT(addr));
+ }
+
+ const uintptr_t good_addr = ZAddress::good(addr);
+ guarantee(oopDesc::is_oop(ZOop::from_address(good_addr)), BAD_OOP_REPORT(addr));
+}
+
+void ZVerifyObjectClosure::do_object(oop o) {
+ if (_visit_referents) {
+ ZVerifyOopClosure<true /* VisitReferents */> cl;
+ o->oop_iterate((OopIterateClosure*)&cl);
+ } else {
+ ZVerifyOopClosure<false /* VisitReferents */> cl;
+ o->oop_iterate(&cl);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zVerify.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZVERIFY_HPP
+#define SHARE_GC_Z_ZVERIFY_HPP
+
+#include "memory/allocation.hpp"
+
+class ZVerify : public AllStatic {
+private:
+ template <typename RootsIterator>
+ static void roots_impl();
+ static void roots(bool verify_weaks);
+
+ static void roots_weak();
+ static void roots_concurrent();
+ static void roots_concurrent_weak();
+
+ static void objects(bool verify_weaks);
+
+ static void roots_and_objects(bool visit_weaks);
+
+public:
+ // Verify strong (non-concurrent) roots. Should always be good.
+ static void roots_strong();
+
+ // Verify all strong roots and references after marking.
+ static void after_mark();
+
+ // Verify strong and weak roots and references.
+ static void after_weak_processing();
+};
+
+class VM_ZVerifyOperation : public VM_Operation {
+public:
+ virtual bool needs_inactive_gc_locker() const {
+ // An inactive GC locker is needed in operations where we change the bad
+ // mask or move objects. Changing the bad mask will invalidate all oops,
+ // which makes it conceptually the same thing as moving all objects.
+ return false;
+ }
+
+ virtual void doit() {
+ ZVerify::after_weak_processing();
+ }
+
+ bool success() const {
+ return true;
+ }
+
+ virtual VMOp_Type type() const { return VMOp_ZVerify; }
+};
+
+#endif // SHARE_GC_Z_ZVERIFY_HPP
--- a/src/hotspot/share/gc/z/z_globals.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/gc/z/z_globals.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -76,6 +76,12 @@
diagnostic(bool, ZVerifyViews, false, \
"Verify heap view accesses") \
\
+ diagnostic(bool, ZVerifyRoots, trueInDebug, \
+ "Verify roots") \
+ \
+ diagnostic(bool, ZVerifyObjects, false, \
+ "Verify objects") \
+ \
diagnostic(bool, ZVerifyMarking, false, \
"Verify marking stacks") \
\
--- a/src/hotspot/share/include/cds.h Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/include/cds.h Mon Jul 22 11:08:27 2019 +0530
@@ -33,10 +33,10 @@
//
// Also, this is a C header file. Do not use C++ here.
-#define NUM_CDS_REGIONS 9
+#define NUM_CDS_REGIONS 8 // this must be the same as MetaspaceShared::n_regions
#define CDS_ARCHIVE_MAGIC 0xf00baba2
#define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
-#define CURRENT_CDS_ARCHIVE_VERSION 5
+#define CURRENT_CDS_ARCHIVE_VERSION 6
#define INVALID_CDS_ARCHIVE_VERSION -1
struct CDSFileMapRegion {
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1106,7 +1106,7 @@
objects_to_revoke->append(Handle(THREAD, kptr->obj()));
}
}
- BiasedLocking::revoke(objects_to_revoke);
+ BiasedLocking::revoke(objects_to_revoke, thread);
}
}
return osr_nm;
--- a/src/hotspot/share/interpreter/templateInterpreter.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/interpreter/templateInterpreter.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,11 @@
#include "interpreter/templateInterpreter.hpp"
#include "interpreter/templateInterpreterGenerator.hpp"
#include "interpreter/templateTable.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
+#include "runtime/safepoint.hpp"
#include "runtime/timerTrace.hpp"
+#include "utilities/copy.hpp"
#ifndef CC_INTERP
@@ -274,18 +277,28 @@
//------------------------------------------------------------------------------------------------------------------------
-// Safepoint suppport
+// Safepoint support
static inline void copy_table(address* from, address* to, int size) {
- // Copy non-overlapping tables. The copy has to occur word wise for MT safety.
- while (size-- > 0) *to++ = *from++;
+ // Copy non-overlapping tables.
+ if (SafepointSynchronize::is_at_safepoint()) {
+ // Nothing is using the table at a safepoint so skip atomic word copy.
+ Copy::disjoint_words((HeapWord*)from, (HeapWord*)to, (size_t)size);
+ } else {
+ // Use atomic word copy when not at a safepoint for safety.
+ Copy::disjoint_words_atomic((HeapWord*)from, (HeapWord*)to, (size_t)size);
+ }
}
void TemplateInterpreter::notice_safepoints() {
if (!_notice_safepoints) {
+ log_debug(interpreter, safepoint)("switching active_table to safept_table.");
// switch to safepoint dispatch table
_notice_safepoints = true;
copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
+ } else {
+ log_debug(interpreter, safepoint)("active_table is already safept_table; "
+ "notice_safepoints() call is no-op.");
}
}
@@ -297,10 +310,17 @@
void TemplateInterpreter::ignore_safepoints() {
if (_notice_safepoints) {
if (!JvmtiExport::should_post_single_step()) {
+ log_debug(interpreter, safepoint)("switching active_table to normal_table.");
// switch to normal dispatch table
_notice_safepoints = false;
copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
+ } else {
+ log_debug(interpreter, safepoint)("single stepping is still active; "
+ "ignoring ignore_safepoints() call.");
}
+ } else {
+ log_debug(interpreter, safepoint)("active_table is already normal_table; "
+ "ignore_safepoints() call is no-op.");
}
}
--- a/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -99,7 +99,6 @@
}
void BFSClosure::process() {
-
process_root_set();
process_queue();
}
@@ -138,7 +137,6 @@
// if we are processinig initial root set, don't add to queue
if (_current_parent != NULL) {
- assert(_current_parent->distance_to_root() == _current_frontier_level, "invariant");
_edge_queue->add(_current_parent, reference);
}
@@ -151,20 +149,8 @@
void BFSClosure::add_chain(const oop* reference, const oop pointee) {
assert(pointee != NULL, "invariant");
assert(NULL == pointee->mark(), "invariant");
-
- const size_t length = _current_parent == NULL ? 1 : _current_parent->distance_to_root() + 2;
- ResourceMark rm;
- Edge* const chain = NEW_RESOURCE_ARRAY(Edge, length);
- size_t idx = 0;
- chain[idx++] = Edge(NULL, reference);
- // aggregate from breadth-first search
- const Edge* current = _current_parent;
- while (current != NULL) {
- chain[idx++] = Edge(NULL, current->reference());
- current = current->parent();
- }
- assert(length == idx, "invariant");
- _edge_store->add_chain(chain, length);
+ Edge leak_edge(_current_parent, reference);
+ _edge_store->put_chain(&leak_edge, _current_parent == NULL ? 1 : _current_frontier_level + 2);
}
void BFSClosure::dfs_fallback() {
@@ -241,3 +227,12 @@
closure_impl(UnifiedOop::encode(ref), pointee);
}
}
+
+void BFSClosure::do_root(const oop* ref) {
+ assert(ref != NULL, "invariant");
+ assert(is_aligned(ref, HeapWordSize), "invariant");
+ assert(*ref != NULL, "invariant");
+ if (!_edge_queue->is_full()) {
+ _edge_queue->add(NULL, ref);
+ }
+}
--- a/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,7 +26,6 @@
#define SHARE_JFR_LEAKPROFILER_CHAINS_BFSCLOSURE_HPP
#include "memory/iterator.hpp"
-#include "oops/oop.hpp"
class BitSet;
class Edge;
@@ -65,6 +64,7 @@
public:
BFSClosure(EdgeQueue* edge_queue, EdgeStore* edge_store, BitSet* mark_bits);
void process();
+ void do_root(const oop* ref);
virtual void do_oop(oop* ref);
virtual void do_oop(narrowOop* ref);
--- a/src/hotspot/share/jfr/leakprofiler/chains/bitset.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/bitset.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -47,7 +47,7 @@
BitMap::idx_t mark_obj(const HeapWord* addr) {
const BitMap::idx_t bit = addr_to_bit(addr);
- _bits.par_set_bit(bit);
+ _bits.set_bit(bit);
return bit;
}
--- a/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,14 +23,14 @@
*/
#include "precompiled.hpp"
+#include "jfr/leakprofiler/chains/bitset.hpp"
#include "jfr/leakprofiler/chains/dfsClosure.hpp"
#include "jfr/leakprofiler/chains/edge.hpp"
#include "jfr/leakprofiler/chains/edgeStore.hpp"
+#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
#include "jfr/leakprofiler/utilities/granularTimer.hpp"
-#include "jfr/leakprofiler/chains/bitset.hpp"
+#include "jfr/leakprofiler/utilities/rootType.hpp"
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
-#include "jfr/leakprofiler/utilities/rootType.hpp"
-#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
@@ -88,15 +88,15 @@
// Mark root set, to avoid going sideways
_max_depth = 1;
_ignore_root_set = false;
- DFSClosure dfs1;
- RootSetClosure::process_roots(&dfs1);
+ DFSClosure dfs;
+ RootSetClosure<DFSClosure> rs(&dfs);
+ rs.process();
// Depth-first search
_max_depth = max_dfs_depth;
_ignore_root_set = true;
assert(_start_edge == NULL, "invariant");
- DFSClosure dfs2;
- RootSetClosure::process_roots(&dfs2);
+ rs.process();
}
void DFSClosure::closure_impl(const oop* reference, const oop pointee) {
@@ -133,30 +133,29 @@
}
void DFSClosure::add_chain() {
- const size_t length = _start_edge == NULL ? _depth + 1 :
- _start_edge->distance_to_root() + 1 + _depth + 1;
+ const size_t array_length = _depth + 2;
ResourceMark rm;
- Edge* const chain = NEW_RESOURCE_ARRAY(Edge, length);
+ Edge* const chain = NEW_RESOURCE_ARRAY(Edge, array_length);
size_t idx = 0;
// aggregate from depth-first search
const DFSClosure* c = this;
while (c != NULL) {
- chain[idx++] = Edge(NULL, c->reference());
+ const size_t next = idx + 1;
+ chain[idx++] = Edge(&chain[next], c->reference());
c = c->parent();
}
-
- assert(idx == _depth + 1, "invariant");
+ assert(_depth + 1 == idx, "invariant");
+ assert(array_length == idx + 1, "invariant");
// aggregate from breadth-first search
- const Edge* current = _start_edge;
- while (current != NULL) {
- chain[idx++] = Edge(NULL, current->reference());
- current = current->parent();
+ if (_start_edge != NULL) {
+ chain[idx++] = *_start_edge;
+ } else {
+ chain[idx - 1] = Edge(NULL, chain[idx - 1].reference());
}
- assert(idx == length, "invariant");
- _edge_store->add_chain(chain, length);
+ _edge_store->put_chain(chain, idx + (_start_edge != NULL ? _start_edge->distance_to_root() : 0));
}
void DFSClosure::do_oop(oop* ref) {
@@ -176,3 +175,11 @@
closure_impl(UnifiedOop::encode(ref), pointee);
}
}
+
+void DFSClosure::do_root(const oop* ref) {
+ assert(ref != NULL, "invariant");
+ assert(is_aligned(ref, HeapWordSize), "invariant");
+ const oop pointee = *ref;
+ assert(pointee != NULL, "invariant");
+ closure_impl(ref, pointee);
+}
--- a/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,7 +26,6 @@
#define SHARE_JFR_LEAKPROFILER_CHAINS_DFSCLOSURE_HPP
#include "memory/iterator.hpp"
-#include "oops/oop.hpp"
class BitSet;
class Edge;
@@ -34,7 +33,7 @@
class EdgeQueue;
// Class responsible for iterating the heap depth-first
-class DFSClosure: public BasicOopIterateClosure {
+class DFSClosure : public BasicOopIterateClosure {
private:
static EdgeStore* _edge_store;
static BitSet* _mark_bits;
@@ -57,6 +56,7 @@
public:
static void find_leaks_from_edge(EdgeStore* edge_store, BitSet* mark_bits, const Edge* start_edge);
static void find_leaks_from_root_set(EdgeStore* edge_store, BitSet* mark_bits);
+ void do_root(const oop* ref);
virtual void do_oop(oop* ref);
virtual void do_oop(narrowOop* ref);
--- a/src/hotspot/share/jfr/leakprofiler/chains/edge.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/edge.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -29,7 +29,7 @@
#include "oops/oopsHierarchy.hpp"
class Edge {
- private:
+ protected:
const Edge* _parent;
const oop* _reference;
public:
--- a/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,37 +27,17 @@
#include "jfr/leakprofiler/chains/edgeUtils.hpp"
#include "oops/oop.inline.hpp"
-RoutableEdge::RoutableEdge() : Edge() {}
-RoutableEdge::RoutableEdge(const Edge* parent, const oop* reference) : Edge(parent, reference),
- _skip_edge(NULL),
- _skip_length(0),
- _processed(false) {}
+StoredEdge::StoredEdge() : Edge() {}
+StoredEdge::StoredEdge(const Edge* parent, const oop* reference) : Edge(parent, reference), _gc_root_id(0), _skip_length(0) {}
-RoutableEdge::RoutableEdge(const Edge& edge) : Edge(edge),
- _skip_edge(NULL),
- _skip_length(0),
- _processed(false) {}
-
-RoutableEdge::RoutableEdge(const RoutableEdge& edge) : Edge(edge),
- _skip_edge(edge._skip_edge),
- _skip_length(edge._skip_length),
- _processed(edge._processed) {}
+StoredEdge::StoredEdge(const Edge& edge) : Edge(edge), _gc_root_id(0), _skip_length(0) {}
-void RoutableEdge::operator=(const RoutableEdge& edge) {
- Edge::operator=(edge);
- _skip_edge = edge._skip_edge;
- _skip_length = edge._skip_length;
- _processed = edge._processed;
-}
+StoredEdge::StoredEdge(const StoredEdge& edge) : Edge(edge), _gc_root_id(edge._gc_root_id), _skip_length(edge._skip_length) {}
-size_t RoutableEdge::logical_distance_to_root() const {
- size_t depth = 0;
- const RoutableEdge* current = logical_parent();
- while (current != NULL) {
- depth++;
- current = current->logical_parent();
- }
- return depth;
+void StoredEdge::operator=(const StoredEdge& edge) {
+ Edge::operator=(edge);
+ _gc_root_id = edge._gc_root_id;
+ _skip_length = edge._skip_length;
}
traceid EdgeStore::_edge_id_counter = 0;
@@ -69,79 +49,12 @@
EdgeStore::~EdgeStore() {
assert(_edges != NULL, "invariant");
delete _edges;
- _edges = NULL;
-}
-
-const Edge* EdgeStore::get_edge(const Edge* edge) const {
- assert(edge != NULL, "invariant");
- EdgeEntry* const entry = _edges->lookup_only(*edge, (uintptr_t)edge->reference());
- return entry != NULL ? entry->literal_addr() : NULL;
-}
-
-const Edge* EdgeStore::put(const Edge* edge) {
- assert(edge != NULL, "invariant");
- const RoutableEdge e = *edge;
- assert(NULL == _edges->lookup_only(e, (uintptr_t)e.reference()), "invariant");
- EdgeEntry& entry = _edges->put(e, (uintptr_t)e.reference());
- return entry.literal_addr();
-}
-
-traceid EdgeStore::get_id(const Edge* edge) const {
- assert(edge != NULL, "invariant");
- EdgeEntry* const entry = _edges->lookup_only(*edge, (uintptr_t)edge->reference());
- assert(entry != NULL, "invariant");
- return entry->id();
-}
-
-traceid EdgeStore::get_root_id(const Edge* edge) const {
- assert(edge != NULL, "invariant");
- const Edge* root = EdgeUtils::root(*edge);
- assert(root != NULL, "invariant");
- return get_id(root);
-}
-
-void EdgeStore::add_chain(const Edge* chain, size_t length) {
- assert(chain != NULL, "invariant");
- assert(length > 0, "invariant");
-
- size_t bottom_index = length - 1;
- const size_t top_index = 0;
-
- const Edge* stored_parent_edge = NULL;
-
- // determine level of shared ancestry
- for (; bottom_index > top_index; --bottom_index) {
- const Edge* stored_edge = get_edge(&chain[bottom_index]);
- if (stored_edge != NULL) {
- stored_parent_edge = stored_edge;
- continue;
- }
- break;
- }
-
- // insertion of new Edges
- for (int i = (int)bottom_index; i >= (int)top_index; --i) {
- Edge edge(stored_parent_edge, chain[i].reference());
- stored_parent_edge = put(&edge);
- }
-
- const oop sample_object = stored_parent_edge->pointee();
- assert(sample_object != NULL, "invariant");
- assert(NULL == sample_object->mark(), "invariant");
-
- // Install the "top" edge of the chain into the sample object mark oop.
- // This associates the sample object with its navigable reference chain.
- sample_object->set_mark(markOop(stored_parent_edge));
}
bool EdgeStore::is_empty() const {
return !_edges->has_entries();
}
-size_t EdgeStore::number_of_entries() const {
- return _edges->cardinality();
-}
-
void EdgeStore::assign_id(EdgeEntry* entry) {
assert(entry != NULL, "invariant");
assert(entry->id() == 0, "invariant");
@@ -153,3 +66,254 @@
assert(entry->hash() == hash, "invariant");
return true;
}
+
+#ifdef ASSERT
+bool EdgeStore::contains(const oop* reference) const {
+ return get(reference) != NULL;
+}
+#endif
+
+StoredEdge* EdgeStore::get(const oop* reference) const {
+ assert(reference != NULL, "invariant");
+ const StoredEdge e(NULL, reference);
+ EdgeEntry* const entry = _edges->lookup_only(e, (uintptr_t)reference);
+ return entry != NULL ? entry->literal_addr() : NULL;
+}
+
+StoredEdge* EdgeStore::put(const oop* reference) {
+ assert(reference != NULL, "invariant");
+ const StoredEdge e(NULL, reference);
+ assert(NULL == _edges->lookup_only(e, (uintptr_t)reference), "invariant");
+ EdgeEntry& entry = _edges->put(e, (uintptr_t)reference);
+ return entry.literal_addr();
+}
+
+traceid EdgeStore::get_id(const Edge* edge) const {
+ assert(edge != NULL, "invariant");
+ EdgeEntry* const entry = _edges->lookup_only(*edge, (uintptr_t)edge->reference());
+ assert(entry != NULL, "invariant");
+ return entry->id();
+}
+
+traceid EdgeStore::gc_root_id(const Edge* edge) const {
+ assert(edge != NULL, "invariant");
+ const traceid gc_root_id = static_cast<const StoredEdge*>(edge)->gc_root_id();
+ if (gc_root_id != 0) {
+ return gc_root_id;
+ }
+ // not cached
+ assert(edge != NULL, "invariant");
+ const Edge* const root = EdgeUtils::root(*edge);
+ assert(root != NULL, "invariant");
+ assert(root->parent() == NULL, "invariant");
+ return get_id(root);
+}
+
+static const Edge* get_skip_ancestor(const Edge** current, size_t distance_to_root, size_t* skip_length) {
+ assert(distance_to_root >= EdgeUtils::root_context, "invariant");
+ assert(*skip_length == 0, "invariant");
+ *skip_length = distance_to_root - (EdgeUtils::root_context - 1);
+ const Edge* const target = EdgeUtils::ancestor(**current, *skip_length);
+ assert(target != NULL, "invariant");
+ assert(target->distance_to_root() + 1 == EdgeUtils::root_context, "invariant");
+ return target;
+}
+
+bool EdgeStore::put_skip_edge(StoredEdge** previous, const Edge** current, size_t distance_to_root) {
+ assert(*previous != NULL, "invariant");
+ assert((*previous)->parent() == NULL, "invariant");
+ assert(*current != NULL, "invariant");
+ assert((*current)->distance_to_root() == distance_to_root, "invariant");
+
+ if (distance_to_root < EdgeUtils::root_context) {
+ // nothing to skip
+ return false;
+ }
+
+ size_t skip_length = 0;
+ const Edge* const skip_ancestor = get_skip_ancestor(current, distance_to_root, &skip_length);
+ assert(skip_ancestor != NULL, "invariant");
+ (*previous)->set_skip_length(skip_length);
+
+ // lookup target
+ StoredEdge* stored_target = get(skip_ancestor->reference());
+ if (stored_target != NULL) {
+ (*previous)->set_parent(stored_target);
+ // linked to existing, complete
+ return true;
+ }
+
+ assert(stored_target == NULL, "invariant");
+ stored_target = put(skip_ancestor->reference());
+ assert(stored_target != NULL, "invariant");
+ (*previous)->set_parent(stored_target);
+ *previous = stored_target;
+ *current = skip_ancestor->parent();
+ return false;
+}
+
+static void link_edge(const StoredEdge* current_stored, StoredEdge** previous) {
+ assert(current_stored != NULL, "invariant");
+ assert(*previous != NULL, "invariant");
+ assert((*previous)->parent() == NULL, "invariant");
+ (*previous)->set_parent(current_stored);
+}
+
+static const StoredEdge* find_closest_skip_edge(const StoredEdge* edge, size_t* distance) {
+ assert(edge != NULL, "invariant");
+ assert(distance != NULL, "invariant");
+ const StoredEdge* current = edge;
+ *distance = 1;
+ while (current != NULL && !current->is_skip_edge()) {
+ ++(*distance);
+ current = current->parent();
+ }
+ return current;
+}
+
+void EdgeStore::link_with_existing_chain(const StoredEdge* current_stored, StoredEdge** previous, size_t previous_length) {
+ assert(current_stored != NULL, "invariant");
+ assert((*previous)->parent() == NULL, "invariant");
+ size_t distance_to_skip_edge; // including the skip edge itself
+ const StoredEdge* const closest_skip_edge = find_closest_skip_edge(current_stored, &distance_to_skip_edge);
+ if (closest_skip_edge == NULL) {
+ // no found skip edge implies root
+ if (distance_to_skip_edge + previous_length <= EdgeUtils::max_ref_chain_depth) {
+ link_edge(current_stored, previous);
+ return;
+ }
+ assert(current_stored->distance_to_root() == distance_to_skip_edge - 2, "invariant");
+ put_skip_edge(previous, reinterpret_cast<const Edge**>(¤t_stored), distance_to_skip_edge - 2);
+ return;
+ }
+ assert(closest_skip_edge->is_skip_edge(), "invariant");
+ if (distance_to_skip_edge + previous_length <= EdgeUtils::leak_context) {
+ link_edge(current_stored, previous);
+ return;
+ }
+ // create a new skip edge with derived information from closest skip edge
+ (*previous)->set_skip_length(distance_to_skip_edge + closest_skip_edge->skip_length());
+ (*previous)->set_parent(closest_skip_edge->parent());
+}
+
+StoredEdge* EdgeStore::link_new_edge(StoredEdge** previous, const Edge** current) {
+ assert(*previous != NULL, "invariant");
+ assert((*previous)->parent() == NULL, "invariant");
+ assert(*current != NULL, "invariant");
+ assert(!contains((*current)->reference()), "invariant");
+ StoredEdge* const stored_edge = put((*current)->reference());
+ assert(stored_edge != NULL, "invariant");
+ link_edge(stored_edge, previous);
+ return stored_edge;
+}
+
+bool EdgeStore::put_edges(StoredEdge** previous, const Edge** current, size_t limit) {
+ assert(*previous != NULL, "invariant");
+ assert(*current != NULL, "invariant");
+ size_t depth = 1;
+ while (*current != NULL && depth < limit) {
+ StoredEdge* stored_edge = get((*current)->reference());
+ if (stored_edge != NULL) {
+ link_with_existing_chain(stored_edge, previous, depth);
+ return true;
+ }
+ stored_edge = link_new_edge(previous, current);
+ assert((*previous)->parent() != NULL, "invariant");
+ *previous = stored_edge;
+ *current = (*current)->parent();
+ ++depth;
+ }
+ return NULL == *current;
+}
+
+// Install the immediate edge into the mark word of the leak candidate object
+StoredEdge* EdgeStore::associate_leak_context_with_candidate(const Edge* edge) {
+ assert(edge != NULL, "invariant");
+ assert(!contains(edge->reference()), "invariant");
+ StoredEdge* const leak_context_edge = put(edge->reference());
+ oop sample_object = edge->pointee();
+ assert(sample_object != NULL, "invariant");
+ assert(NULL == sample_object->mark(), "invariant");
+ sample_object->set_mark(markOop(leak_context_edge));
+ return leak_context_edge;
+}
+
+/*
+ * The purpose of put_chain() is to reify the edge sequence
+ * discovered during heap traversal with a normalized logical copy.
+ * This copy consist of two sub-sequences and a connecting link (skip edge).
+ *
+ * "current" can be thought of as the cursor (search) edge, it is not in the edge store.
+ * "previous" is always an edge in the edge store.
+ * The leak context edge is the edge adjacent to the leak candidate object, always an edge in the edge store.
+ */
+void EdgeStore::put_chain(const Edge* chain, size_t length) {
+ assert(chain != NULL, "invariant");
+ assert(chain->distance_to_root() + 1 == length, "invariant");
+ StoredEdge* const leak_context_edge = associate_leak_context_with_candidate(chain);
+ assert(leak_context_edge != NULL, "invariant");
+ assert(leak_context_edge->parent() == NULL, "invariant");
+
+ if (1 == length) {
+ return;
+ }
+
+ const Edge* current = chain->parent();
+ assert(current != NULL, "invariant");
+ StoredEdge* previous = leak_context_edge;
+
+ // a leak context is the sequence of (limited) edges reachable from the leak candidate
+ if (put_edges(&previous, ¤t, EdgeUtils::leak_context)) {
+ // complete
+ assert(previous != NULL, "invariant");
+ put_chain_epilogue(leak_context_edge, EdgeUtils::root(*previous));
+ return;
+ }
+
+ const size_t distance_to_root = length > EdgeUtils::leak_context ? length - 1 - EdgeUtils::leak_context : length - 1;
+ assert(current->distance_to_root() == distance_to_root, "invariant");
+
+ // a skip edge is the logical link
+ // connecting the leak context sequence with the root context sequence
+ if (put_skip_edge(&previous, ¤t, distance_to_root)) {
+ // complete
+ assert(previous != NULL, "invariant");
+ assert(previous->is_skip_edge(), "invariant");
+ assert(previous->parent() != NULL, "invariant");
+ put_chain_epilogue(leak_context_edge, EdgeUtils::root(*previous->parent()));
+ return;
+ }
+
+ assert(current->distance_to_root() < EdgeUtils::root_context, "invariant");
+
+ // a root context is the sequence of (limited) edges reachable from the root
+ put_edges(&previous, ¤t, EdgeUtils::root_context);
+ assert(previous != NULL, "invariant");
+ put_chain_epilogue(leak_context_edge, EdgeUtils::root(*previous));
+}
+
+void EdgeStore::put_chain_epilogue(StoredEdge* leak_context_edge, const Edge* root) const {
+ assert(leak_context_edge != NULL, "invariant");
+ assert(root != NULL, "invariant");
+ store_gc_root_id_in_leak_context_edge(leak_context_edge, root);
+ assert(leak_context_edge->distance_to_root() + 1 <= EdgeUtils::max_ref_chain_depth, "invariant");
+}
+
+// To avoid another traversal to resolve the root edge id later,
+// cache it in the immediate leak context edge for fast retrieval.
+void EdgeStore::store_gc_root_id_in_leak_context_edge(StoredEdge* leak_context_edge, const Edge* root) const {
+ assert(leak_context_edge != NULL, "invariant");
+ assert(leak_context_edge->gc_root_id() == 0, "invariant");
+ assert(root != NULL, "invariant");
+ assert(root->parent() == NULL, "invariant");
+ assert(root->distance_to_root() == 0, "invariant");
+ const StoredEdge* const stored_root = static_cast<const StoredEdge*>(root);
+ traceid root_id = stored_root->gc_root_id();
+ if (root_id == 0) {
+ root_id = get_id(root);
+ stored_root->set_gc_root_id(root_id);
+ }
+ assert(root_id != 0, "invariant");
+ leak_context_edge->set_gc_root_id(root_id);
+ assert(leak_context_edge->gc_root_id() == stored_root->gc_root_id(), "invariant");
+}
--- a/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,64 +25,40 @@
#ifndef SHARE_JFR_LEAKPROFILER_CHAINS_EDGESTORE_HPP
#define SHARE_JFR_LEAKPROFILER_CHAINS_EDGESTORE_HPP
+#include "jfr/leakprofiler/chains/edge.hpp"
#include "jfr/utilities/jfrHashtable.hpp"
-#include "jfr/leakprofiler/chains/edge.hpp"
#include "memory/allocation.hpp"
typedef u8 traceid;
-class RoutableEdge : public Edge {
+class StoredEdge : public Edge {
private:
- mutable const RoutableEdge* _skip_edge;
- mutable size_t _skip_length;
- mutable bool _processed;
+ mutable traceid _gc_root_id;
+ size_t _skip_length;
public:
- RoutableEdge();
- RoutableEdge(const Edge* parent, const oop* reference);
- RoutableEdge(const Edge& edge);
- RoutableEdge(const RoutableEdge& edge);
- void operator=(const RoutableEdge& edge);
-
- const RoutableEdge* skip_edge() const { return _skip_edge; }
- size_t skip_length() const { return _skip_length; }
+ StoredEdge();
+ StoredEdge(const Edge* parent, const oop* reference);
+ StoredEdge(const Edge& edge);
+ StoredEdge(const StoredEdge& edge);
+ void operator=(const StoredEdge& edge);
- bool is_skip_edge() const { return _skip_edge != NULL; }
- bool processed() const { return _processed; }
- bool is_sentinel() const {
- return _skip_edge == NULL && _skip_length == 1;
- }
-
- void set_skip_edge(const RoutableEdge* edge) const {
- assert(!is_skip_edge(), "invariant");
- assert(edge != this, "invariant");
- _skip_edge = edge;
- }
+ traceid gc_root_id() const { return _gc_root_id; }
+ void set_gc_root_id(traceid root_id) const { _gc_root_id = root_id; }
- void set_skip_length(size_t length) const {
- _skip_length = length;
- }
-
- void set_processed() const {
- assert(!_processed, "invariant");
- _processed = true;
- }
+ bool is_skip_edge() const { return _skip_length != 0; }
+ size_t skip_length() const { return _skip_length; }
+ void set_skip_length(size_t length) { _skip_length = length; }
- // true navigation according to physical tree representation
- const RoutableEdge* physical_parent() const {
- return static_cast<const RoutableEdge*>(parent());
- }
+ void set_parent(const Edge* edge) { this->_parent = edge; }
- // logical navigation taking skip levels into account
- const RoutableEdge* logical_parent() const {
- return is_skip_edge() ? skip_edge() : physical_parent();
+ StoredEdge* parent() const {
+ return const_cast<StoredEdge*>(static_cast<const StoredEdge*>(Edge::parent()));
}
-
- size_t logical_distance_to_root() const;
};
class EdgeStore : public CHeapObj<mtTracing> {
- typedef HashTableHost<RoutableEdge, traceid, Entry, EdgeStore> EdgeHashTable;
+ typedef HashTableHost<StoredEdge, traceid, Entry, EdgeStore> EdgeHashTable;
typedef EdgeHashTable::HashEntry EdgeEntry;
template <typename,
typename,
@@ -90,6 +66,9 @@
typename,
size_t>
friend class HashTableHost;
+ friend class EventEmitter;
+ friend class ObjectSampleWriter;
+ friend class ObjectSampleCheckpoint;
private:
static traceid _edge_id_counter;
EdgeHashTable* _edges;
@@ -98,22 +77,31 @@
void assign_id(EdgeEntry* entry);
bool equals(const Edge& query, uintptr_t hash, const EdgeEntry* entry);
- const Edge* get_edge(const Edge* edge) const;
- const Edge* put(const Edge* edge);
+ StoredEdge* get(const oop* reference) const;
+ StoredEdge* put(const oop* reference);
+ traceid gc_root_id(const Edge* edge) const;
+
+ bool put_edges(StoredEdge** previous, const Edge** current, size_t length);
+ bool put_skip_edge(StoredEdge** previous, const Edge** current, size_t distance_to_root);
+ void put_chain_epilogue(StoredEdge* leak_context_edge, const Edge* root) const;
+
+ StoredEdge* associate_leak_context_with_candidate(const Edge* edge);
+ void store_gc_root_id_in_leak_context_edge(StoredEdge* leak_context_edge, const Edge* root) const;
+ StoredEdge* link_new_edge(StoredEdge** previous, const Edge** current);
+ void link_with_existing_chain(const StoredEdge* current_stored, StoredEdge** previous, size_t previous_length);
+
+ template <typename T>
+ void iterate(T& functor) const { _edges->iterate_value<T>(functor); }
+
+ DEBUG_ONLY(bool contains(const oop* reference) const;)
public:
EdgeStore();
~EdgeStore();
- void add_chain(const Edge* chain, size_t length);
bool is_empty() const;
- size_t number_of_entries() const;
-
traceid get_id(const Edge* edge) const;
- traceid get_root_id(const Edge* edge) const;
-
- template <typename T>
- void iterate_edges(T& functor) const { _edges->iterate_value<T>(functor); }
+ void put_chain(const Edge* chain, size_t length);
};
#endif // SHARE_JFR_LEAKPROFILER_CHAINS_EDGESTORE_HPP
--- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,11 +38,7 @@
return (const Edge*)edge.pointee()->mark() == &edge;
}
-bool EdgeUtils::is_root(const Edge& edge) {
- return edge.is_root();
-}
-
-static int field_offset(const Edge& edge) {
+static int field_offset(const StoredEdge& edge) {
assert(!edge.is_root(), "invariant");
const oop ref_owner = edge.reference_owner();
assert(ref_owner != NULL, "invariant");
@@ -56,7 +52,7 @@
return offset;
}
-static const InstanceKlass* field_type(const Edge& edge) {
+static const InstanceKlass* field_type(const StoredEdge& edge) {
assert(!edge.is_root() || !EdgeUtils::is_array_element(edge), "invariant");
return (const InstanceKlass*)edge.reference_owner_klass();
}
@@ -138,175 +134,18 @@
current = parent;
parent = current->parent();
}
- return current;
-}
-
-// The number of references associated with the leak node;
-// can be viewed as the leak node "context".
-// Used to provide leak context for a "capped/skipped" reference chain.
-static const size_t leak_context = 100;
-
-// The number of references associated with the root node;
-// can be viewed as the root node "context".
-// Used to provide root context for a "capped/skipped" reference chain.
-static const size_t root_context = 100;
-
-// A limit on the reference chain depth to be serialized,
-static const size_t max_ref_chain_depth = leak_context + root_context;
-
-const RoutableEdge* skip_to(const RoutableEdge& edge, size_t skip_length) {
- const RoutableEdge* current = &edge;
- const RoutableEdge* parent = current->physical_parent();
- size_t seek = 0;
- while (parent != NULL && seek != skip_length) {
- seek++;
- current = parent;
- parent = parent->physical_parent();
- }
- return current;
-}
-
-#ifdef ASSERT
-static void validate_skip_target(const RoutableEdge* skip_target) {
- assert(skip_target != NULL, "invariant");
- assert(skip_target->distance_to_root() + 1 == root_context, "invariant");
- assert(skip_target->is_sentinel(), "invariant");
-}
-
-static void validate_new_skip_edge(const RoutableEdge* new_skip_edge, const RoutableEdge* last_skip_edge, size_t adjustment) {
- assert(new_skip_edge != NULL, "invariant");
- assert(new_skip_edge->is_skip_edge(), "invariant");
- if (last_skip_edge != NULL) {
- const RoutableEdge* const target = skip_to(*new_skip_edge->logical_parent(), adjustment);
- validate_skip_target(target->logical_parent());
- return;
- }
- assert(last_skip_edge == NULL, "invariant");
- // only one level of logical indirection
- validate_skip_target(new_skip_edge->logical_parent());
-}
-#endif // ASSERT
-
-static void install_logical_route(const RoutableEdge* new_skip_edge, size_t skip_target_distance) {
- assert(new_skip_edge != NULL, "invariant");
- assert(!new_skip_edge->is_skip_edge(), "invariant");
- assert(!new_skip_edge->processed(), "invariant");
- const RoutableEdge* const skip_target = skip_to(*new_skip_edge, skip_target_distance);
- assert(skip_target != NULL, "invariant");
- new_skip_edge->set_skip_edge(skip_target);
- new_skip_edge->set_skip_length(skip_target_distance);
- assert(new_skip_edge->is_skip_edge(), "invariant");
- assert(new_skip_edge->logical_parent() == skip_target, "invariant");
-}
-
-static const RoutableEdge* find_last_skip_edge(const RoutableEdge& edge, size_t& distance) {
- assert(distance == 0, "invariant");
- const RoutableEdge* current = &edge;
- while (current != NULL) {
- if (current->is_skip_edge() && current->skip_edge()->is_sentinel()) {
- return current;
- }
- current = current->physical_parent();
- ++distance;
- }
+ assert(current != NULL, "invariant");
return current;
}
-static void collapse_overlapping_chain(const RoutableEdge& edge,
- const RoutableEdge* first_processed_edge,
- size_t first_processed_distance) {
- assert(first_processed_edge != NULL, "invariant");
- // first_processed_edge is already processed / written
- assert(first_processed_edge->processed(), "invariant");
- assert(first_processed_distance + 1 <= leak_context, "invariant");
-
- // from this first processed edge, attempt to fetch the last skip edge
- size_t last_skip_edge_distance = 0;
- const RoutableEdge* const last_skip_edge = find_last_skip_edge(*first_processed_edge, last_skip_edge_distance);
- const size_t distance_discovered = first_processed_distance + last_skip_edge_distance + 1;
-
- if (distance_discovered <= leak_context || (last_skip_edge == NULL && distance_discovered <= max_ref_chain_depth)) {
- // complete chain can be accommodated without modification
- return;
- }
-
- // backtrack one edge from existing processed edge
- const RoutableEdge* const new_skip_edge = skip_to(edge, first_processed_distance - 1);
- assert(new_skip_edge != NULL, "invariant");
- assert(!new_skip_edge->processed(), "invariant");
- assert(new_skip_edge->parent() == first_processed_edge, "invariant");
-
- size_t adjustment = 0;
- if (last_skip_edge != NULL) {
- assert(leak_context - 1 > first_processed_distance - 1, "invariant");
- adjustment = leak_context - first_processed_distance - 1;
- assert(last_skip_edge_distance + 1 > adjustment, "invariant");
- install_logical_route(new_skip_edge, last_skip_edge_distance + 1 - adjustment);
- } else {
- install_logical_route(new_skip_edge, last_skip_edge_distance + 1 - root_context);
- new_skip_edge->logical_parent()->set_skip_length(1); // sentinel
+const Edge* EdgeUtils::ancestor(const Edge& edge, size_t distance) {
+ const Edge* current = &edge;
+ const Edge* parent = current->parent();
+ size_t seek = 0;
+ while (parent != NULL && seek != distance) {
+ seek++;
+ current = parent;
+ parent = parent->parent();
}
-
- DEBUG_ONLY(validate_new_skip_edge(new_skip_edge, last_skip_edge, adjustment);)
-}
-
-static void collapse_non_overlapping_chain(const RoutableEdge& edge,
- const RoutableEdge* first_processed_edge,
- size_t first_processed_distance) {
- assert(first_processed_edge != NULL, "invariant");
- assert(!first_processed_edge->processed(), "invariant");
- // this implies that the first "processed" edge is the leak context relative "leaf"
- assert(first_processed_distance + 1 == leak_context, "invariant");
-
- const size_t distance_to_root = edge.distance_to_root();
- if (distance_to_root + 1 <= max_ref_chain_depth) {
- // complete chain can be accommodated without constructing a skip edge
- return;
- }
-
- install_logical_route(first_processed_edge, distance_to_root + 1 - first_processed_distance - root_context);
- first_processed_edge->logical_parent()->set_skip_length(1); // sentinel
-
- DEBUG_ONLY(validate_new_skip_edge(first_processed_edge, NULL, 0);)
-}
-
-static const RoutableEdge* processed_edge(const RoutableEdge& edge, size_t& distance) {
- assert(distance == 0, "invariant");
- const RoutableEdge* current = &edge;
- while (current != NULL && distance < leak_context - 1) {
- if (current->processed()) {
- return current;
- }
- current = current->physical_parent();
- ++distance;
- }
- assert(distance <= leak_context - 1, "invariant");
return current;
}
-
-/*
- * Some vocabulary:
- * -----------
- * "Context" is an interval in the chain, it is associcated with an edge and it signifies a number of connected edges.
- * "Processed / written" means an edge that has already been serialized.
- * "Skip edge" is an edge that contains additional information for logical routing purposes.
- * "Skip target" is an edge used as a destination for a skip edge
- */
-void EdgeUtils::collapse_chain(const RoutableEdge& edge) {
- assert(is_leak_edge(edge), "invariant");
-
- // attempt to locate an already processed edge inside current leak context (if any)
- size_t first_processed_distance = 0;
- const RoutableEdge* const first_processed_edge = processed_edge(edge, first_processed_distance);
- if (first_processed_edge == NULL) {
- return;
- }
-
- if (first_processed_edge->processed()) {
- collapse_overlapping_chain(edge, first_processed_edge, first_processed_distance);
- } else {
- collapse_non_overlapping_chain(edge, first_processed_edge, first_processed_distance);
- }
-
- assert(edge.logical_distance_to_root() + 1 <= max_ref_chain_depth, "invariant");
-}
--- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -28,15 +28,17 @@
#include "memory/allocation.hpp"
class Edge;
-class RoutableEdge;
class Symbol;
class EdgeUtils : public AllStatic {
public:
- static bool is_leak_edge(const Edge& edge);
+ static const size_t leak_context = 100;
+ static const size_t root_context = 100;
+ static const size_t max_ref_chain_depth = leak_context + root_context;
+ static bool is_leak_edge(const Edge& edge);
static const Edge* root(const Edge& edge);
- static bool is_root(const Edge& edge);
+ static const Edge* ancestor(const Edge& edge, size_t distance);
static bool is_array_element(const Edge& edge);
static int array_index(const Edge& edge);
@@ -44,8 +46,6 @@
static const Symbol* field_name_symbol(const Edge& edge);
static jshort field_modifiers(const Edge& edge);
-
- static void collapse_chain(const RoutableEdge& edge);
};
#endif // SHARE_JFR_LEAKPROFILER_CHAINS_EDGEUTILS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "jfr/leakprofiler/leakProfiler.hpp"
+#include "jfr/leakprofiler/chains/bfsClosure.hpp"
+#include "jfr/leakprofiler/chains/bitset.hpp"
+#include "jfr/leakprofiler/chains/dfsClosure.hpp"
+#include "jfr/leakprofiler/chains/edge.hpp"
+#include "jfr/leakprofiler/chains/edgeQueue.hpp"
+#include "jfr/leakprofiler/chains/edgeStore.hpp"
+#include "jfr/leakprofiler/chains/objectSampleMarker.hpp"
+#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
+#include "jfr/leakprofiler/chains/edgeStore.hpp"
+#include "jfr/leakprofiler/chains/objectSampleMarker.hpp"
+#include "jfr/leakprofiler/chains/pathToGcRootsOperation.hpp"
+#include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
+#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
+#include "jfr/leakprofiler/sampling/objectSample.hpp"
+#include "jfr/leakprofiler/sampling/objectSampler.hpp"
+#include "jfr/leakprofiler/utilities/granularTimer.hpp"
+#include "logging/log.hpp"
+#include "memory/universe.hpp"
+#include "oops/markOop.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/safepoint.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+PathToGcRootsOperation::PathToGcRootsOperation(ObjectSampler* sampler, EdgeStore* edge_store, int64_t cutoff, bool emit_all) :
+ _sampler(sampler),_edge_store(edge_store), _cutoff_ticks(cutoff), _emit_all(emit_all) {}
+
+/* The EdgeQueue is backed by directly managed virtual memory.
+ * We will attempt to dimension an initial reservation
+ * in proportion to the size of the heap (represented by heap_region).
+ * Initial memory reservation: 5% of the heap OR at least 32 Mb
+ * Commit ratio: 1 : 10 (subject to allocation granularties)
+ */
+static size_t edge_queue_memory_reservation(const MemRegion& heap_region) {
+ const size_t memory_reservation_bytes = MAX2(heap_region.byte_size() / 20, 32*M);
+ assert(memory_reservation_bytes >= (size_t)32*M, "invariant");
+ return memory_reservation_bytes;
+}
+
+static size_t edge_queue_memory_commit_size(size_t memory_reservation_bytes) {
+ const size_t memory_commit_block_size_bytes = memory_reservation_bytes / 10;
+ assert(memory_commit_block_size_bytes >= (size_t)3*M, "invariant");
+ return memory_commit_block_size_bytes;
+}
+
+static void log_edge_queue_summary(const EdgeQueue& edge_queue) {
+ log_trace(jfr, system)("EdgeQueue reserved size total: " SIZE_FORMAT " [KB]", edge_queue.reserved_size() / K);
+ log_trace(jfr, system)("EdgeQueue edges total: " SIZE_FORMAT, edge_queue.top());
+ log_trace(jfr, system)("EdgeQueue liveset total: " SIZE_FORMAT " [KB]", edge_queue.live_set() / K);
+ if (edge_queue.reserved_size() > 0) {
+ log_trace(jfr, system)("EdgeQueue commit reserve ratio: %f\n",
+ ((double)edge_queue.live_set() / (double)edge_queue.reserved_size()));
+ }
+}
+
+void PathToGcRootsOperation::doit() {
+ assert(SafepointSynchronize::is_at_safepoint(), "invariant");
+ assert(_cutoff_ticks > 0, "invariant");
+
+ // The bitset used for marking is dimensioned as a function of the heap size
+ const MemRegion heap_region = Universe::heap()->reserved_region();
+ BitSet mark_bits(heap_region);
+
+ // The edge queue is dimensioned as a fraction of the heap size
+ const size_t edge_queue_reservation_size = edge_queue_memory_reservation(heap_region);
+ EdgeQueue edge_queue(edge_queue_reservation_size, edge_queue_memory_commit_size(edge_queue_reservation_size));
+
+ // The initialize() routines will attempt to reserve and allocate backing storage memory.
+ // Failure to accommodate will render root chain processing impossible.
+ // As a fallback on failure, just write out the existing samples, flat, without chains.
+ if (!(mark_bits.initialize() && edge_queue.initialize())) {
+ log_warning(jfr)("Unable to allocate memory for root chain processing");
+ return;
+ }
+
+ // Save the original markWord for the potential leak objects,
+ // to be restored on function exit
+ ObjectSampleMarker marker;
+ if (ObjectSampleCheckpoint::mark(_sampler, marker, _emit_all) == 0) {
+ // no valid samples to process
+ return;
+ }
+
+ // Necessary condition for attempting a root set iteration
+ Universe::heap()->ensure_parsability(false);
+
+ BFSClosure bfs(&edge_queue, _edge_store, &mark_bits);
+ RootSetClosure<BFSClosure> roots(&bfs);
+
+ GranularTimer::start(_cutoff_ticks, 1000000);
+ roots.process();
+ if (edge_queue.is_full()) {
+ // Pathological case where roots don't fit in queue
+ // Do a depth-first search, but mark roots first
+ // to avoid walking sideways over roots
+ DFSClosure::find_leaks_from_root_set(_edge_store, &mark_bits);
+ } else {
+ bfs.process();
+ }
+ GranularTimer::stop();
+ log_edge_queue_summary(edge_queue);
+
+ // Emit old objects including their reference chains as events
+ EventEmitter emitter(GranularTimer::start_time(), GranularTimer::end_time());
+ emitter.write_events(_sampler, _edge_store, _emit_all);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_JFR_LEAKPROFILER_CHAINS_PATHTOGCROOTSOPERATION_HPP
+#define SHARE_JFR_LEAKPROFILER_CHAINS_PATHTOGCROOTSOPERATION_HPP
+
+#include "jfr/leakprofiler/utilities/vmOperation.hpp"
+
+class EdgeStore;
+class ObjectSampler;
+
+// Safepoint operation for finding paths to gc roots
+class PathToGcRootsOperation : public OldObjectVMOperation {
+ private:
+ ObjectSampler* _sampler;
+ EdgeStore* const _edge_store;
+ const int64_t _cutoff_ticks;
+ const bool _emit_all;
+
+ public:
+ PathToGcRootsOperation(ObjectSampler* sampler, EdgeStore* edge_store, int64_t cutoff, bool emit_all);
+ virtual void doit();
+};
+
+#endif // SHARE_JFR_LEAKPROFILER_CHAINS_PATHTOGCROOTSOPERATION_HPP
--- a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -28,27 +28,26 @@
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/strongRootsScope.hpp"
+#include "jfr/leakprofiler/chains/bfsClosure.hpp"
+#include "jfr/leakprofiler/chains/dfsClosure.hpp"
#include "jfr/leakprofiler/chains/edgeQueue.hpp"
#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
-#include "jfr/leakprofiler/utilities/saveRestore.hpp"
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
+#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.hpp"
#include "services/management.hpp"
#include "utilities/align.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
-RootSetClosure::RootSetClosure(EdgeQueue* edge_queue) :
- _edge_queue(edge_queue) {
-}
+template <typename Delegate>
+RootSetClosure<Delegate>::RootSetClosure(Delegate* delegate) : _delegate(delegate) {}
-void RootSetClosure::do_oop(oop* ref) {
+template <typename Delegate>
+void RootSetClosure<Delegate>::do_oop(oop* ref) {
assert(ref != NULL, "invariant");
// We discard unaligned root references because
// our reference tagging scheme will use
@@ -62,50 +61,39 @@
}
assert(is_aligned(ref, HeapWordSize), "invariant");
- const oop pointee = *ref;
- if (pointee != NULL) {
- closure_impl(ref, pointee);
+ if (*ref != NULL) {
+ _delegate->do_root(ref);
}
}
-void RootSetClosure::do_oop(narrowOop* ref) {
+template <typename Delegate>
+void RootSetClosure<Delegate>::do_oop(narrowOop* ref) {
assert(ref != NULL, "invariant");
assert(is_aligned(ref, sizeof(narrowOop)), "invariant");
const oop pointee = RawAccess<>::oop_load(ref);
if (pointee != NULL) {
- closure_impl(UnifiedOop::encode(ref), pointee);
- }
-}
-
-void RootSetClosure::closure_impl(const oop* reference, const oop pointee) {
- if (!_edge_queue->is_full()) {
- _edge_queue->add(NULL, reference);
+ _delegate->do_root(UnifiedOop::encode(ref));
}
}
-void RootSetClosure::add_to_queue(EdgeQueue* edge_queue) {
- RootSetClosure rs(edge_queue);
- process_roots(&rs);
+class RootSetClosureMarkScope : public MarkScope {};
+
+template <typename Delegate>
+void RootSetClosure<Delegate>::process() {
+ RootSetClosureMarkScope mark_scope;
+ CLDToOopClosure cldt_closure(this, ClassLoaderData::_claim_none);
+ ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
+ CodeBlobToOopClosure blobs(this, false);
+ Threads::oops_do(this, &blobs);
+ ObjectSynchronizer::oops_do(this);
+ Universe::oops_do(this);
+ JNIHandles::oops_do(this);
+ JvmtiExport::oops_do(this);
+ SystemDictionary::oops_do(this);
+ Management::oops_do(this);
+ StringTable::oops_do(this);
+ AOTLoader::oops_do(this);
}
-class RootSetClosureMarkScope : public MarkScope {
-};
-
-void RootSetClosure::process_roots(OopClosure* closure) {
- SaveRestoreCLDClaimBits save_restore_cld_claim_bits;
- RootSetClosureMarkScope mark_scope;
-
- CLDToOopClosure cldt_closure(closure, ClassLoaderData::_claim_strong);
- ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
- CodeBlobToOopClosure blobs(closure, false);
- Threads::oops_do(closure, &blobs);
- ObjectSynchronizer::oops_do(closure);
- Universe::oops_do(closure);
- JNIHandles::oops_do(closure);
- JvmtiExport::oops_do(closure);
- SystemDictionary::oops_do(closure);
- Management::oops_do(closure);
- StringTable::oops_do(closure);
- AOTLoader::oops_do(closure);
- JVMCI_ONLY(JVMCI::oops_do(closure);)
-}
+template class RootSetClosure<BFSClosure>;
+template class RootSetClosure<DFSClosure>;
--- a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,18 +26,14 @@
#define SHARE_JFR_LEAKPROFILER_CHAINS_ROOTSETCLOSURE_HPP
#include "memory/iterator.hpp"
-#include "oops/oop.hpp"
-class EdgeQueue;
-
+template <typename Delegate>
class RootSetClosure: public BasicOopIterateClosure {
private:
- RootSetClosure(EdgeQueue* edge_queue);
- EdgeQueue* _edge_queue;
- void closure_impl(const oop* reference, const oop pointee);
+ Delegate* const _delegate;
public:
- static void add_to_queue(EdgeQueue* edge_queue);
- static void process_roots(OopClosure* closure);
+ RootSetClosure(Delegate* delegate);
+ void process();
virtual void do_oop(oop* reference);
virtual void do_oop(narrowOop* reference);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "jfr/jfrEvents.hpp"
+#include "jfr/leakprofiler/chains/edgeStore.hpp"
+#include "jfr/leakprofiler/chains/pathToGcRootsOperation.hpp"
+#include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
+#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
+#include "jfr/leakprofiler/sampling/objectSample.hpp"
+#include "jfr/leakprofiler/sampling/objectSampler.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/markOop.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/vmThread.hpp"
+
+EventEmitter::EventEmitter(const JfrTicks& start_time, const JfrTicks& end_time) :
+ _start_time(start_time),
+ _end_time(end_time),
+ _thread(Thread::current()),
+ _jfr_thread_local(_thread->jfr_thread_local()),
+ _thread_id(_thread->jfr_thread_local()->thread_id()) {}
+
+EventEmitter::~EventEmitter() {
+ // restore / reset thread local stack trace and thread id
+ _jfr_thread_local->set_thread_id(_thread_id);
+ _jfr_thread_local->clear_cached_stack_trace();
+}
+
+void EventEmitter::emit(ObjectSampler* sampler, int64_t cutoff_ticks, bool emit_all) {
+ assert(sampler != NULL, "invariant");
+
+ ResourceMark rm;
+ EdgeStore edge_store;
+ if (cutoff_ticks <= 0) {
+ // no reference chains
+ JfrTicks time_stamp = JfrTicks::now();
+ EventEmitter emitter(time_stamp, time_stamp);
+ emitter.write_events(sampler, &edge_store, emit_all);
+ return;
+ }
+ // events emitted with reference chains require a safepoint operation
+ PathToGcRootsOperation op(sampler, &edge_store, cutoff_ticks, emit_all);
+ VMThread::execute(&op);
+}
+
+size_t EventEmitter::write_events(ObjectSampler* object_sampler, EdgeStore* edge_store, bool emit_all) {
+ assert(_thread == Thread::current(), "invariant");
+ assert(_thread->jfr_thread_local() == _jfr_thread_local, "invariant");
+ assert(object_sampler != NULL, "invariant");
+ assert(edge_store != NULL, "invariant");
+
+ const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
+ size_t count = 0;
+
+ const ObjectSample* current = object_sampler->first();
+ while (current != NULL) {
+ ObjectSample* prev = current->prev();
+ if (current->is_alive_and_older_than(last_sweep)) {
+ write_event(current, edge_store);
+ ++count;
+ }
+ current = prev;
+ }
+
+ if (count > 0) {
+ // serialize associated checkpoints and potential chains
+ ObjectSampleCheckpoint::write(object_sampler, edge_store, emit_all, _thread);
+ }
+ return count;
+}
+
+static int array_size(const oop object) {
+ assert(object != NULL, "invariant");
+ if (object->is_array()) {
+ return arrayOop(object)->length();
+ }
+ return min_jint;
+}
+
+void EventEmitter::write_event(const ObjectSample* sample, EdgeStore* edge_store) {
+ assert(sample != NULL, "invariant");
+ assert(!sample->is_dead(), "invariant");
+ assert(edge_store != NULL, "invariant");
+ assert(_jfr_thread_local != NULL, "invariant");
+
+ const oop* object_addr = sample->object_addr();
+ traceid gc_root_id = 0;
+ const Edge* edge = NULL;
+ if (SafepointSynchronize::is_at_safepoint()) {
+ edge = (const Edge*)(*object_addr)->mark();
+ }
+ if (edge == NULL) {
+ // In order to dump out a representation of the event
+ // even though it was not reachable / too long to reach,
+ // we need to register a top level edge for this object.
+ edge = edge_store->put(object_addr);
+ } else {
+ gc_root_id = edge_store->gc_root_id(edge);
+ }
+
+ assert(edge != NULL, "invariant");
+ const traceid object_id = edge_store->get_id(edge);
+ assert(object_id != 0, "invariant");
+
+ EventOldObjectSample e(UNTIMED);
+ e.set_starttime(_start_time);
+ e.set_endtime(_end_time);
+ e.set_allocationTime(sample->allocation_time());
+ e.set_lastKnownHeapUsage(sample->heap_used_at_last_gc());
+ e.set_object(object_id);
+ e.set_arrayElements(array_size(edge->pointee()));
+ e.set_root(gc_root_id);
+
+ // Temporarily assigning both the stack trace id and thread id
+ // onto the thread local data structure of the emitter thread (for the duration
+ // of the commit() call). This trick provides a means to override
+ // the event generation mechanism by injecting externally provided id's.
+ // At this particular location, it allows us to emit an old object event
+ // supplying information from where the actual sampling occurred.
+ _jfr_thread_local->set_cached_stack_trace_id(sample->stack_trace_id());
+ assert(sample->has_thread(), "invariant");
+ _jfr_thread_local->set_thread_id(sample->thread_id());
+ e.commit();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_JFR_LEAKPROFILER_CHECKPOINT_EVENTEMITTER_HPP
+#define SHARE_JFR_LEAKPROFILER_CHECKPOINT_EVENTEMITTER_HPP
+
+#include "memory/allocation.hpp"
+#include "jfr/utilities/jfrTime.hpp"
+
+typedef u8 traceid;
+
+class EdgeStore;
+class JfrThreadLocal;
+class ObjectSample;
+class ObjectSampler;
+class Thread;
+
+class EventEmitter : public CHeapObj<mtTracing> {
+ friend class LeakProfiler;
+ friend class PathToGcRootsOperation;
+ private:
+ const JfrTicks& _start_time;
+ const JfrTicks& _end_time;
+ Thread* _thread;
+ JfrThreadLocal* _jfr_thread_local;
+ traceid _thread_id;
+
+ EventEmitter(const JfrTicks& start_time, const JfrTicks& end_time);
+ ~EventEmitter();
+
+ void write_event(const ObjectSample* sample, EdgeStore* edge_store);
+ size_t write_events(ObjectSampler* sampler, EdgeStore* store, bool emit_all);
+
+ static void emit(ObjectSampler* sampler, int64_t cutoff_ticks, bool emit_all);
+};
+
+#endif // SHARE_JFR_LEAKPROFILER_CHECKPOINT_EVENTEMITTER_HPP
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -181,21 +181,18 @@
}
};
-void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool resume) {
- assert(class_unload ? SafepointSynchronize::is_at_safepoint() : LeakProfiler::is_suspended(), "invariant");
-
+void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload) {
if (!writer.has_data()) {
- if (!class_unload) {
- LeakProfiler::resume();
- }
- assert(LeakProfiler::is_running(), "invariant");
return;
}
assert(writer.has_data(), "invariant");
const JfrCheckpointBlobHandle h_cp = writer.checkpoint_blob();
- const ObjectSampler* const object_sampler = LeakProfiler::object_sampler();
+ // Class unload implies a safepoint.
+ // Not class unload implies the object sampler is locked, because it was claimed exclusively earlier.
+ // Therefore: direct access the object sampler instance is safe.
+ const ObjectSampler* const object_sampler = ObjectSampler::sampler();
assert(object_sampler != NULL, "invariant");
ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
@@ -203,80 +200,71 @@
CheckpointInstall install(h_cp);
if (class_unload) {
- if (last != NULL) {
- // all samples need the class unload information
- do_samples(last, NULL, install);
- }
- assert(LeakProfiler::is_running(), "invariant");
+ // all samples need class unload information
+ do_samples(last, NULL, install);
return;
}
// only new samples since last resolved checkpoint
if (last != last_resolved) {
do_samples(last, last_resolved, install);
- if (resume) {
- const_cast<ObjectSampler*>(object_sampler)->set_last_resolved(last);
- }
- }
- assert(LeakProfiler::is_suspended(), "invariant");
- if (resume) {
- LeakProfiler::resume();
- assert(LeakProfiler::is_running(), "invariant");
+ const_cast<ObjectSampler*>(object_sampler)->set_last_resolved(last);
}
}
-void ObjectSampleCheckpoint::write(const EdgeStore* edge_store, bool emit_all, Thread* thread) {
+void ObjectSampleCheckpoint::write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) {
+ assert(sampler != NULL, "invariant");
assert(edge_store != NULL, "invariant");
assert(thread != NULL, "invariant");
+
static bool types_registered = false;
if (!types_registered) {
JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType());
JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType());
types_registered = true;
}
- const ObjectSampler* const object_sampler = LeakProfiler::object_sampler();
- assert(object_sampler != NULL, "invariant");
- const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
- ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
+
+ const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value();
+ ObjectSample* const last = const_cast<ObjectSample*>(sampler->last());
{
JfrCheckpointWriter writer(false, false, thread);
CheckpointWrite checkpoint_write(writer, last_sweep);
do_samples(last, NULL, checkpoint_write);
}
+
CheckpointStateReset state_reset(last_sweep);
do_samples(last, NULL, state_reset);
+
if (!edge_store->is_empty()) {
// java object and chain representations
JfrCheckpointWriter writer(false, true, thread);
ObjectSampleWriter osw(writer, edge_store);
- edge_store->iterate_edges(osw);
+ edge_store->iterate(osw);
}
}
-WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(JfrStackTraceRepository& repo) :
- _stack_trace_repo(repo) {
+int ObjectSampleCheckpoint::mark(ObjectSampler* object_sampler, ObjectSampleMarker& marker, bool emit_all) {
+ assert(object_sampler != NULL, "invariant");
+ ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
+ if (last == NULL) {
+ return 0;
+ }
+ const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
+ SampleMark mark(marker, last_sweep);
+ do_samples(last, NULL, mark);
+ return mark.count();
}
+WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(ObjectSampler* sampler, JfrStackTraceRepository& repo) :
+ _sampler(sampler), _stack_trace_repo(repo) {}
+
bool WriteObjectSampleStacktrace::process() {
- assert(SafepointSynchronize::is_at_safepoint(), "invariant");
- if (!LeakProfiler::is_running()) {
- return true;
- }
- // Suspend the LeakProfiler subsystem
- // to ensure stable samples even
- // after we return from the safepoint.
- LeakProfiler::suspend();
- assert(!LeakProfiler::is_running(), "invariant");
- assert(LeakProfiler::is_suspended(), "invariant");
+ assert(LeakProfiler::is_running(), "invariant");
+ assert(_sampler != NULL, "invariant");
- const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
- assert(object_sampler != NULL, "invariant");
- assert(LeakProfiler::is_suspended(), "invariant");
-
- ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
- const ObjectSample* const last_resolved = object_sampler->last_resolved();
+ ObjectSample* const last = const_cast<ObjectSample*>(_sampler->last());
+ const ObjectSample* const last_resolved = _sampler->last_resolved();
if (last == last_resolved) {
- assert(LeakProfiler::is_suspended(), "invariant");
return true;
}
@@ -294,27 +282,13 @@
}
if (count == 0) {
writer.set_context(ctx);
- assert(LeakProfiler::is_suspended(), "invariant");
return true;
}
assert(count > 0, "invariant");
writer.write_count((u4)count, count_offset);
JfrStackTraceRepository::write_metadata(writer);
- ObjectSampleCheckpoint::install(writer, false, false);
- assert(LeakProfiler::is_suspended(), "invariant");
+ // install the stacktrace checkpoint information to the candidates
+ ObjectSampleCheckpoint::install(writer, false);
return true;
}
-
-int ObjectSampleCheckpoint::mark(ObjectSampleMarker& marker, bool emit_all) {
- const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
- assert(object_sampler != NULL, "invariant");
- ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
- if (last == NULL) {
- return 0;
- }
- const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
- SampleMark mark(marker, last_sweep);
- do_samples(last, NULL, mark);
- return mark.count();
-}
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,25 +26,26 @@
#define SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLECHECKPOINT_HPP
#include "memory/allocation.hpp"
-#include "utilities/exceptions.hpp"
class EdgeStore;
+class JfrCheckpointWriter;
class JfrStackTraceRepository;
-class JfrCheckpointWriter;
class ObjectSampleMarker;
+class ObjectSampler;
class ObjectSampleCheckpoint : AllStatic {
public:
- static void install(JfrCheckpointWriter& writer, bool class_unload, bool resume);
- static void write(const EdgeStore* edge_store, bool emit_all, Thread* thread);
- static int mark(ObjectSampleMarker& marker, bool emit_all);
+ static void install(JfrCheckpointWriter& writer, bool class_unload);
+ static void write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread);
+ static int mark(ObjectSampler* sampler, ObjectSampleMarker& marker, bool emit_all);
};
class WriteObjectSampleStacktrace : public StackObj {
private:
+ ObjectSampler* const _sampler;
JfrStackTraceRepository& _stack_trace_repo;
public:
- WriteObjectSampleStacktrace(JfrStackTraceRepository& repo);
+ WriteObjectSampleStacktrace(ObjectSampler* sampler, JfrStackTraceRepository& repo);
bool process();
};
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -350,7 +350,7 @@
return 1;
}
-static traceid get_root_description_info_id(const Edge& edge, traceid id) {
+static traceid get_gc_root_description_info_id(const Edge& edge, traceid id) {
assert(edge.is_root(), "invariant");
if (EdgeUtils::is_leak_edge(edge)) {
return 0;
@@ -518,7 +518,7 @@
}
}
-static void add_old_object_sample_info(const Edge* current, traceid id) {
+static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
assert(current != NULL, "invariant");
if (sample_infos == NULL) {
sample_infos = new SampleInfo();
@@ -528,11 +528,11 @@
assert(oosi != NULL, "invariant");
oosi->_id = id;
oosi->_data._object = current->pointee();
- oosi->_data._reference_id = current->is_root() ? (traceid)0 : id;
+ oosi->_data._reference_id = current->parent() == NULL ? (traceid)0 : id;
sample_infos->store(oosi);
}
-static void add_reference_info(const RoutableEdge* current, traceid id, traceid parent_id) {
+static void add_reference_info(const StoredEdge* current, traceid id, traceid parent_id) {
assert(current != NULL, "invariant");
if (ref_infos == NULL) {
ref_infos = new RefInfo();
@@ -544,37 +544,43 @@
ri->_id = id;
ri->_data._array_info_id = !current->is_skip_edge() ? get_array_info_id(*current, id) : 0;
- ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ?
- get_field_info_id(*current) : (traceid)0;
+ ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ? get_field_info_id(*current) : (traceid)0;
ri->_data._old_object_sample_id = parent_id;
ri->_data._skip = current->skip_length();
ref_infos->store(ri);
}
-static traceid add_root_info(const Edge* root, traceid id) {
- assert(root != NULL, "invariant");
- assert(root->is_root(), "invariant");
- return get_root_description_info_id(*root, id);
+static bool is_gc_root(const StoredEdge* current) {
+ assert(current != NULL, "invariant");
+ return current->parent() == NULL && current->gc_root_id() != 0;
}
-void ObjectSampleWriter::write(const RoutableEdge* edge) {
+static traceid add_gc_root_info(const StoredEdge* root, traceid id) {
+ assert(root != NULL, "invariant");
+ assert(is_gc_root(root), "invariant");
+ return get_gc_root_description_info_id(*root, id);
+}
+
+void ObjectSampleWriter::write(const StoredEdge* edge) {
assert(edge != NULL, "invariant");
const traceid id = _store->get_id(edge);
add_old_object_sample_info(edge, id);
- const RoutableEdge* parent = edge->logical_parent();
+ const StoredEdge* const parent = edge->parent();
if (parent != NULL) {
add_reference_info(edge, id, _store->get_id(parent));
} else {
- assert(edge->is_root(), "invariant");
- add_root_info(edge, id);
+ if (is_gc_root(edge)) {
+ assert(edge->gc_root_id() == id, "invariant");
+ add_gc_root_info(edge, id);
+ }
}
}
-ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, const EdgeStore* store) :
+ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store) :
_writer(writer),
_store(store) {
assert(store != NULL, "invariant");
- assert(store->number_of_entries() > 0, "invariant");
+ assert(!store->is_empty(), "invariant");
sample_infos = NULL;
ref_infos = NULL;
array_infos = NULL;
@@ -590,26 +596,7 @@
write_root_descriptors(_writer);
}
-void ObjectSampleWriter::write_chain(const RoutableEdge& edge) {
- assert(EdgeUtils::is_leak_edge(edge), "invariant");
- if (edge.processed()) {
- return;
- }
- EdgeUtils::collapse_chain(edge);
- const RoutableEdge* current = &edge;
- while (current != NULL) {
- if (current->processed()) {
- return;
- }
- write(current);
- current->set_processed();
- current = current->logical_parent();
- }
-}
-
-bool ObjectSampleWriter::operator()(const RoutableEdge& edge) {
- if (EdgeUtils::is_leak_edge(edge)) {
- write_chain(edge);
- }
+bool ObjectSampleWriter::operator()(StoredEdge& e) {
+ write(&e);
return true;
}
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -30,21 +30,17 @@
class Edge;
class EdgeStore;
class JfrCheckpointWriter;
-class RoutableEdge;
+class StoredEdge;
class ObjectSampleWriter : public StackObj {
private:
JfrCheckpointWriter& _writer;
- const EdgeStore* const _store;
-
- void write(const RoutableEdge* edge);
- void write_chain(const RoutableEdge& edge);
-
+ EdgeStore* const _store;
+ void write(const StoredEdge* edge);
public:
- ObjectSampleWriter(JfrCheckpointWriter& writer, const EdgeStore* store);
+ ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store);
~ObjectSampleWriter();
-
- bool operator()(const RoutableEdge& edge);
+ bool operator()(StoredEdge& edge);
};
#endif // SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLEWRITER_HPP
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -41,9 +41,6 @@
#include "runtime/vframe_hp.hpp"
#include "services/management.hpp"
#include "utilities/growableArray.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
class ReferenceLocateClosure : public OopClosure {
protected:
@@ -106,7 +103,6 @@
bool do_management_roots();
bool do_string_table_roots();
bool do_aot_loader_roots();
- JVMCI_ONLY(bool do_jvmci_roots();)
bool do_roots();
@@ -132,7 +128,7 @@
bool ReferenceToRootClosure::do_cldg_roots() {
assert(!complete(), "invariant");
ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);
- CLDToOopClosure cldt_closure(&rlc, ClassLoaderData::_claim_strong);
+ CLDToOopClosure cldt_closure(&rlc, ClassLoaderData::_claim_none);
ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
return rlc.complete();
}
@@ -193,15 +189,6 @@
return rcl.complete();
}
-#if INCLUDE_JVMCI
-bool ReferenceToRootClosure::do_jvmci_roots() {
- assert(!complete(), "invariant");
- ReferenceLocateClosure rcl(_callback, OldObjectRoot::_jvmci, OldObjectRoot::_type_undetermined, NULL);
- JVMCI::oops_do(&rcl);
- return rcl.complete();
-}
-#endif
-
bool ReferenceToRootClosure::do_roots() {
assert(!complete(), "invariant");
assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
@@ -252,13 +239,6 @@
return true;
}
-#if INCLUDE_JVMCI
- if (do_jvmci_roots()) {
- _complete = true;
- return true;
- }
-#endif
-
return false;
}
@@ -435,9 +415,6 @@
};
void RootResolver::resolve(RootCallback& callback) {
-
- // Need to clear cld claim bit before starting
- ClassLoaderDataGraph::clear_claimed_marks();
RootResolverMarkScope mark_scope;
// thread local roots
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,8 +25,8 @@
#ifndef SHARE_JFR_LEAKPROFILER_CHECKPOINT_ROOTRESOLVER_HPP
#define SHARE_JFR_LEAKPROFILER_CHECKPOINT_ROOTRESOLVER_HPP
+#include "jfr/leakprofiler/utilities/rootType.hpp"
#include "memory/allocation.hpp"
-#include "jfr/leakprofiler/utilities/rootType.hpp"
#include "oops/oopsHierarchy.hpp"
struct RootCallbackInfo {
--- a/src/hotspot/share/jfr/leakprofiler/emitEventOperation.cpp Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-#include "precompiled.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "jfr/jfrEvents.hpp"
-#include "jfr/leakprofiler/utilities/granularTimer.hpp"
-#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
-#include "jfr/leakprofiler/chains/edge.hpp"
-#include "jfr/leakprofiler/chains/edgeQueue.hpp"
-#include "jfr/leakprofiler/chains/edgeStore.hpp"
-#include "jfr/leakprofiler/chains/bitset.hpp"
-#include "jfr/leakprofiler/sampling/objectSample.hpp"
-#include "jfr/leakprofiler/leakProfiler.hpp"
-#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
-#include "jfr/leakprofiler/sampling/objectSampler.hpp"
-#include "jfr/leakprofiler/emitEventOperation.hpp"
-#include "jfr/leakprofiler/chains/bfsClosure.hpp"
-#include "jfr/leakprofiler/chains/dfsClosure.hpp"
-#include "jfr/leakprofiler/chains/objectSampleMarker.hpp"
-#include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
-#include "jfr/support/jfrThreadId.hpp"
-#include "logging/log.hpp"
-#include "memory/resourceArea.hpp"
-#include "memory/universe.hpp"
-#include "oops/markOop.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/safepoint.hpp"
-#include "runtime/vmThread.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-/* The EdgeQueue is backed by directly managed virtual memory.
- * We will attempt to dimension an initial reservation
- * in proportion to the size of the heap (represented by heap_region).
- * Initial memory reservation: 5% of the heap OR at least 32 Mb
- * Commit ratio: 1 : 10 (subject to allocation granularties)
- */
-static size_t edge_queue_memory_reservation(const MemRegion& heap_region) {
- const size_t memory_reservation_bytes = MAX2(heap_region.byte_size() / 20, 32*M);
- assert(memory_reservation_bytes >= (size_t)32*M, "invariant");
- return memory_reservation_bytes;
-}
-
-static size_t edge_queue_memory_commit_size(size_t memory_reservation_bytes) {
- const size_t memory_commit_block_size_bytes = memory_reservation_bytes / 10;
- assert(memory_commit_block_size_bytes >= (size_t)3*M, "invariant");
- return memory_commit_block_size_bytes;
-}
-
-static void log_edge_queue_summary(const EdgeQueue& edge_queue) {
- log_trace(jfr, system)("EdgeQueue reserved size total: " SIZE_FORMAT " [KB]", edge_queue.reserved_size() / K);
- log_trace(jfr, system)("EdgeQueue edges total: " SIZE_FORMAT, edge_queue.top());
- log_trace(jfr, system)("EdgeQueue liveset total: " SIZE_FORMAT " [KB]", edge_queue.live_set() / K);
- if (edge_queue.reserved_size() > 0) {
- log_trace(jfr, system)("EdgeQueue commit reserve ratio: %f\n",
- ((double)edge_queue.live_set() / (double)edge_queue.reserved_size()));
- }
-}
-
-void EmitEventOperation::doit() {
- assert(LeakProfiler::is_running(), "invariant");
- _object_sampler = LeakProfiler::object_sampler();
- assert(_object_sampler != NULL, "invariant");
-
- _vm_thread = VMThread::vm_thread();
- assert(_vm_thread == Thread::current(), "invariant");
- _vm_thread_local = _vm_thread->jfr_thread_local();
- assert(_vm_thread_local != NULL, "invariant");
- assert(_vm_thread->jfr_thread_local()->thread_id() == JFR_THREAD_ID(_vm_thread), "invariant");
-
- // The VM_Operation::evaluate() which invoked doit()
- // contains a top level ResourceMark
-
- // save the original markWord for the potential leak objects
- // to be restored on function exit
- ObjectSampleMarker marker;
- if (ObjectSampleCheckpoint::mark(marker, _emit_all) == 0) {
- return;
- }
-
- EdgeStore edge_store;
-
- GranularTimer::start(_cutoff_ticks, 1000000);
- if (_cutoff_ticks <= 0) {
- // no chains
- write_events(&edge_store);
- return;
- }
-
- assert(_cutoff_ticks > 0, "invariant");
-
- // The bitset used for marking is dimensioned as a function of the heap size
- const MemRegion heap_region = Universe::heap()->reserved_region();
- BitSet mark_bits(heap_region);
-
- // The edge queue is dimensioned as a fraction of the heap size
- const size_t edge_queue_reservation_size = edge_queue_memory_reservation(heap_region);
- EdgeQueue edge_queue(edge_queue_reservation_size, edge_queue_memory_commit_size(edge_queue_reservation_size));
-
- // The initialize() routines will attempt to reserve and allocate backing storage memory.
- // Failure to accommodate will render root chain processing impossible.
- // As a fallback on failure, just write out the existing samples, flat, without chains.
- if (!(mark_bits.initialize() && edge_queue.initialize())) {
- log_warning(jfr)("Unable to allocate memory for root chain processing");
- write_events(&edge_store);
- return;
- }
-
- // necessary condition for attempting a root set iteration
- Universe::heap()->ensure_parsability(false);
-
- RootSetClosure::add_to_queue(&edge_queue);
- if (edge_queue.is_full()) {
- // Pathological case where roots don't fit in queue
- // Do a depth-first search, but mark roots first
- // to avoid walking sideways over roots
- DFSClosure::find_leaks_from_root_set(&edge_store, &mark_bits);
- } else {
- BFSClosure bfs(&edge_queue, &edge_store, &mark_bits);
- bfs.process();
- }
- GranularTimer::stop();
- write_events(&edge_store);
- log_edge_queue_summary(edge_queue);
-}
-
-int EmitEventOperation::write_events(EdgeStore* edge_store) {
- assert(_object_sampler != NULL, "invariant");
- assert(edge_store != NULL, "invariant");
- assert(_vm_thread != NULL, "invariant");
- assert(_vm_thread_local != NULL, "invariant");
- assert(SafepointSynchronize::is_at_safepoint(), "invariant");
-
- // save thread id in preparation for thread local trace data manipulations
- const traceid vmthread_id = _vm_thread_local->thread_id();
- assert(_vm_thread_local->thread_id() == JFR_THREAD_ID(_vm_thread), "invariant");
-
- const jlong last_sweep = _emit_all ? max_jlong : _object_sampler->last_sweep().value();
- int count = 0;
-
- const ObjectSample* current = _object_sampler->first();
- while (current != NULL) {
- ObjectSample* prev = current->prev();
- if (current->is_alive_and_older_than(last_sweep)) {
- write_event(current, edge_store);
- ++count;
- }
- current = prev;
- }
-
- // restore thread local stack trace and thread id
- _vm_thread_local->set_thread_id(vmthread_id);
- _vm_thread_local->clear_cached_stack_trace();
- assert(_vm_thread_local->thread_id() == JFR_THREAD_ID(_vm_thread), "invariant");
-
- if (count > 0) {
- // serialize assoicated checkpoints
- ObjectSampleCheckpoint::write(edge_store, _emit_all, _vm_thread);
- }
- return count;
-}
-
-static int array_size(const oop object) {
- assert(object != NULL, "invariant");
- if (object->is_array()) {
- return arrayOop(object)->length();
- }
- return min_jint;
-}
-
-void EmitEventOperation::write_event(const ObjectSample* sample, EdgeStore* edge_store) {
- assert(sample != NULL, "invariant");
- assert(!sample->is_dead(), "invariant");
- assert(edge_store != NULL, "invariant");
- assert(_vm_thread_local != NULL, "invariant");
- const oop* object_addr = sample->object_addr();
- assert(*object_addr != NULL, "invariant");
-
- const Edge* edge = (const Edge*)(*object_addr)->mark();
- traceid gc_root_id = 0;
- if (edge == NULL) {
- // In order to dump out a representation of the event
- // even though it was not reachable / too long to reach,
- // we need to register a top level edge for this object
- Edge e(NULL, object_addr);
- edge_store->add_chain(&e, 1);
- edge = (const Edge*)(*object_addr)->mark();
- } else {
- gc_root_id = edge_store->get_root_id(edge);
- }
-
- assert(edge != NULL, "invariant");
- assert(edge->pointee() == *object_addr, "invariant");
- const traceid object_id = edge_store->get_id(edge);
- assert(object_id != 0, "invariant");
-
- EventOldObjectSample e(UNTIMED);
- e.set_starttime(GranularTimer::start_time());
- e.set_endtime(GranularTimer::end_time());
- e.set_allocationTime(sample->allocation_time());
- e.set_lastKnownHeapUsage(sample->heap_used_at_last_gc());
- e.set_object(object_id);
- e.set_arrayElements(array_size(*object_addr));
- e.set_root(gc_root_id);
-
- // Temporarily assigning both the stack trace id and thread id
- // onto the thread local data structure of the VMThread (for the duration
- // of the commit() call). This trick provides a means to override
- // the event generation mechanism by injecting externally provided id's.
- // Here, in particular, this allows us to emit an old object event
- // supplying information from where the actual sampling occurred.
- _vm_thread_local->set_cached_stack_trace_id(sample->stack_trace_id());
- assert(sample->has_thread(), "invariant");
- _vm_thread_local->set_thread_id(sample->thread_id());
- e.commit();
-}
--- a/src/hotspot/share/jfr/leakprofiler/emitEventOperation.hpp Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_JFR_LEAKPROFILER_EMITEVENTOPERATION_HPP
-#define SHARE_JFR_LEAKPROFILER_EMITEVENTOPERATION_HPP
-
-#include "runtime/vmOperations.hpp"
-
-class BFSClosure;
-class EdgeStore;
-class EdgeQueue;
-class JfrThreadData;
-class ObjectSample;
-class ObjectSampler;
-
-class VMThread;
-
-// Safepoint operation for emitting object sample events
-class EmitEventOperation : public VM_Operation {
- private:
- jlong _cutoff_ticks;
- bool _emit_all;
- VMThread* _vm_thread;
- JfrThreadLocal* _vm_thread_local;
- ObjectSampler* _object_sampler;
-
- void write_event(const ObjectSample* sample, EdgeStore* edge_store);
- int write_events(EdgeStore* edge_store);
-
- public:
- EmitEventOperation(jlong cutoff_ticks, bool emit_all) :
- _cutoff_ticks(cutoff_ticks),
- _emit_all(emit_all),
- _vm_thread(NULL),
- _vm_thread_local(NULL),
- _object_sampler(NULL) {
- }
-
- VMOp_Type type() const {
- return VMOp_GC_HeapInspection;
- }
-
- Mode evaluation_mode() const {
- return _safepoint;
- }
-
- virtual void doit();
-};
-
-#endif // SHARE_JFR_LEAKPROFILER_EMITEVENTOPERATION_HPP
--- a/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,25 +23,31 @@
*/
#include "precompiled.hpp"
-#include "jfr/leakprofiler/emitEventOperation.hpp"
#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/leakprofiler/startOperation.hpp"
#include "jfr/leakprofiler/stopOperation.hpp"
+#include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
#include "jfr/recorder/service/jfrOptionSet.hpp"
+#include "logging/log.hpp"
#include "memory/iterator.hpp"
-#include "oops/oop.hpp"
-#include "runtime/atomic.hpp"
-#include "runtime/orderAccess.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-#include "utilities/ostream.hpp"
+
+bool LeakProfiler::is_running() {
+ return ObjectSampler::is_created();
+}
-// Only to be updated during safepoint
-ObjectSampler* LeakProfiler::_object_sampler = NULL;
+bool LeakProfiler::start(int sample_count) {
+ if (is_running()) {
+ return true;
+ }
-static volatile jbyte suspended = 0;
-bool LeakProfiler::start(jint sample_count) {
+ // Allows user to disable leak profiler on command line by setting queue size to zero.
+ if (sample_count == 0) {
+ return false;
+ }
+
if (UseZGC) {
log_warning(jfr)("LeakProfiler is currently not supported in combination with ZGC");
return false;
@@ -52,49 +58,56 @@
return false;
}
- if (_object_sampler != NULL) {
- // already started
- return true;
+ assert(!is_running(), "invariant");
+ assert(sample_count > 0, "invariant");
+
+ // schedule the safepoint operation for installing the object sampler
+ StartOperation op(sample_count);
+ VMThread::execute(&op);
+
+ if (!is_running()) {
+ log_trace(jfr, system)("Object sampling could not be started because the sampler could not be allocated");
+ return false;
}
- // Allows user to disable leak profiler on command line by setting queue size to zero.
- if (sample_count > 0) {
- StartOperation op(sample_count);
- VMThread::execute(&op);
- return _object_sampler != NULL;
- }
- return false;
+ assert(is_running(), "invariant");
+ log_trace(jfr, system)("Object sampling started");
+ return true;
}
bool LeakProfiler::stop() {
- if (_object_sampler == NULL) {
- // already stopped/not started
- return true;
+ if (!is_running()) {
+ return false;
}
+
+ // schedule the safepoint operation for uninstalling and destroying the object sampler
StopOperation op;
VMThread::execute(&op);
- return _object_sampler == NULL;
+
+ assert(!is_running(), "invariant");
+ log_trace(jfr, system)("Object sampling stopped");
+ return true;
}
-void LeakProfiler::emit_events(jlong cutoff_ticks, bool emit_all) {
+void LeakProfiler::emit_events(int64_t cutoff_ticks, bool emit_all) {
if (!is_running()) {
return;
}
- EmitEventOperation op(cutoff_ticks, emit_all);
- VMThread::execute(&op);
+ // exclusive access to object sampler instance
+ ObjectSampler* const sampler = ObjectSampler::acquire();
+ assert(sampler != NULL, "invariant");
+ EventEmitter::emit(sampler, cutoff_ticks, emit_all);
+ ObjectSampler::release();
}
void LeakProfiler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
assert(SafepointSynchronize::is_at_safepoint(),
"Leak Profiler::oops_do(...) may only be called during safepoint");
-
- if (_object_sampler != NULL) {
- _object_sampler->oops_do(is_alive, f);
+ if (is_running()) {
+ ObjectSampler::oops_do(is_alive, f);
}
}
-void LeakProfiler::sample(HeapWord* object,
- size_t size,
- JavaThread* thread) {
+void LeakProfiler::sample(HeapWord* object, size_t size, JavaThread* thread) {
assert(is_running(), "invariant");
assert(thread != NULL, "invariant");
assert(thread->thread_state() == _thread_in_vm, "invariant");
@@ -104,39 +117,5 @@
return;
}
- _object_sampler->add(object, size, thread);
-}
-
-ObjectSampler* LeakProfiler::object_sampler() {
- assert(is_suspended() || SafepointSynchronize::is_at_safepoint(),
- "Leak Profiler::object_sampler() may only be called during safepoint");
- return _object_sampler;
-}
-
-void LeakProfiler::set_object_sampler(ObjectSampler* object_sampler) {
- assert(SafepointSynchronize::is_at_safepoint(),
- "Leak Profiler::set_object_sampler() may only be called during safepoint");
- _object_sampler = object_sampler;
-}
-
-bool LeakProfiler::is_running() {
- return _object_sampler != NULL && !suspended;
+ ObjectSampler::sample(object, size, thread);
}
-
-bool LeakProfiler::is_suspended() {
- return _object_sampler != NULL && suspended;
-}
-
-void LeakProfiler::resume() {
- assert(is_suspended(), "invariant");
- OrderAccess::storestore();
- Atomic::store((jbyte)0, &suspended);
- assert(is_running(), "invariant");
-}
-
-void LeakProfiler::suspend() {
- assert(SafepointSynchronize::is_at_safepoint(), "invariant");
- assert(_object_sampler != NULL, "invariant");
- assert(!is_suspended(), "invariant");
- suspended = (jbyte)1; // safepoint visible
-}
--- a/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -28,36 +28,16 @@
#include "memory/allocation.hpp"
class BoolObjectClosure;
-class ObjectSampler;
class OopClosure;
class JavaThread;
-class Thread;
class LeakProfiler : public AllStatic {
- friend class ClassUnloadTypeSet;
- friend class EmitEventOperation;
- friend class ObjectSampleCheckpoint;
- friend class StartOperation;
- friend class StopOperation;
- friend class TypeSet;
- friend class WriteObjectSampleStacktrace;
-
- private:
- static ObjectSampler* _object_sampler;
-
- static void set_object_sampler(ObjectSampler* object_sampler);
- static ObjectSampler* object_sampler();
-
- static void suspend();
- static void resume();
- static bool is_suspended();
-
public:
- static bool start(jint sample_count);
+ static bool start(int sample_count);
static bool stop();
- static void emit_events(jlong cutoff_ticks, bool emit_all);
static bool is_running();
+ static void emit_events(int64_t cutoff_ticks, bool emit_all);
static void sample(HeapWord* object, size_t size, JavaThread* thread);
// Called by GC
--- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*
*/
+
#include "precompiled.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/leakprofiler/sampling/objectSample.hpp"
@@ -35,8 +36,18 @@
#include "logging/log.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
+#include "runtime/safepoint.hpp"
#include "runtime/thread.hpp"
+static ObjectSampler* _instance = NULL;
+
+static ObjectSampler& instance() {
+ assert(_instance != NULL, "invariant");
+ return *_instance;
+}
+
ObjectSampler::ObjectSampler(size_t size) :
_priority_queue(new SamplePriorityQueue(size)),
_list(new SampleList(size)),
@@ -44,7 +55,6 @@
_total_allocated(0),
_threshold(0),
_size(size),
- _tryLock(0),
_dead_samples(false) {}
ObjectSampler::~ObjectSampler() {
@@ -54,32 +64,110 @@
_list = NULL;
}
-void ObjectSampler::add(HeapWord* obj, size_t allocated, JavaThread* thread) {
+bool ObjectSampler::create(size_t size) {
+ assert(SafepointSynchronize::is_at_safepoint(), "invariant");
+ assert(_instance == NULL, "invariant");
+ _instance = new ObjectSampler(size);
+ return _instance != NULL;
+}
+
+bool ObjectSampler::is_created() {
+ return _instance != NULL;
+}
+
+ObjectSampler* ObjectSampler::sampler() {
+ assert(is_created(), "invariant");
+ return _instance;
+}
+
+void ObjectSampler::destroy() {
+ assert(SafepointSynchronize::is_at_safepoint(), "invariant");
+ if (_instance != NULL) {
+ ObjectSampler* const sampler = _instance;
+ _instance = NULL;
+ delete sampler;
+ }
+}
+
+static volatile int _lock = 0;
+
+ObjectSampler* ObjectSampler::acquire() {
+ assert(is_created(), "invariant");
+ while (Atomic::cmpxchg(1, &_lock, 0) == 1) {}
+ return _instance;
+}
+
+void ObjectSampler::release() {
+ assert(is_created(), "invariant");
+ OrderAccess::fence();
+ _lock = 0;
+}
+
+static traceid get_thread_id(JavaThread* thread) {
assert(thread != NULL, "invariant");
- const traceid thread_id = thread->threadObj() != NULL ? thread->jfr_thread_local()->thread_id() : 0;
+ if (thread->threadObj() == NULL) {
+ return 0;
+ }
+ const JfrThreadLocal* const tl = thread->jfr_thread_local();
+ assert(tl != NULL, "invariant");
+ if (!tl->has_thread_checkpoint()) {
+ JfrCheckpointManager::create_thread_checkpoint(thread);
+ }
+ assert(tl->has_thread_checkpoint(), "invariant");
+ return tl->thread_id();
+}
+
+// Populates the thread local stack frames, but does not add them
+// to the stacktrace repository (...yet, see stacktrace_id() below)
+//
+void ObjectSampler::fill_stacktrace(JfrStackTrace* stacktrace, JavaThread* thread) {
+ assert(stacktrace != NULL, "invariant");
+ assert(thread != NULL, "invariant");
+ if (JfrEventSetting::has_stacktrace(EventOldObjectSample::eventId)) {
+ JfrStackTraceRepository::fill_stacktrace_for(thread, stacktrace, 0);
+ }
+}
+
+// We were successful in acquiring the try lock and have been selected for adding a sample.
+// Go ahead with installing our previously taken stacktrace into the stacktrace repository.
+//
+traceid ObjectSampler::stacktrace_id(const JfrStackTrace* stacktrace, JavaThread* thread) {
+ assert(stacktrace != NULL, "invariant");
+ assert(stacktrace->hash() != 0, "invariant");
+ const traceid stacktrace_id = JfrStackTraceRepository::add(stacktrace, thread);
+ thread->jfr_thread_local()->set_cached_stack_trace_id(stacktrace_id, stacktrace->hash());
+ return stacktrace_id;
+}
+
+void ObjectSampler::sample(HeapWord* obj, size_t allocated, JavaThread* thread) {
+ assert(thread != NULL, "invariant");
+ assert(is_created(), "invariant");
+
+ const traceid thread_id = get_thread_id(thread);
if (thread_id == 0) {
return;
}
- assert(thread_id != 0, "invariant");
-
- if (!thread->jfr_thread_local()->has_thread_checkpoint()) {
- JfrCheckpointManager::create_thread_checkpoint(thread);
- assert(thread->jfr_thread_local()->has_thread_checkpoint(), "invariant");
- }
- traceid stack_trace_id = 0;
- unsigned int stack_trace_hash = 0;
- if (JfrEventSetting::has_stacktrace(EventOldObjectSample::eventId)) {
- stack_trace_id = JfrStackTraceRepository::record(thread, 0, &stack_trace_hash);
- thread->jfr_thread_local()->set_cached_stack_trace_id(stack_trace_id, stack_trace_hash);
- }
+ const JfrThreadLocal* const tl = thread->jfr_thread_local();
+ JfrStackTrace stacktrace(tl->stackframes(), tl->stackdepth());
+ fill_stacktrace(&stacktrace, thread);
- JfrTryLock tryLock(&_tryLock);
+ // try enter critical section
+ JfrTryLock tryLock(&_lock);
if (!tryLock.has_lock()) {
log_trace(jfr, oldobject, sampling)("Skipping old object sample due to lock contention");
return;
}
+ instance().add(obj, allocated, thread_id, &stacktrace, thread);
+}
+
+void ObjectSampler::add(HeapWord* obj, size_t allocated, traceid thread_id, JfrStackTrace* stacktrace, JavaThread* thread) {
+ assert(stacktrace != NULL, "invariant");
+ assert(thread_id != 0, "invariant");
+ assert(thread != NULL, "invariant");
+ assert(thread->jfr_thread_local()->has_thread_checkpoint(), "invariant");
+
if (_dead_samples) {
scavenge();
assert(!_dead_samples, "invariant");
@@ -101,13 +189,13 @@
}
assert(sample != NULL, "invariant");
- assert(thread_id != 0, "invariant");
sample->set_thread_id(thread_id);
sample->set_thread_checkpoint(thread->jfr_thread_local()->thread_checkpoint());
- if (stack_trace_id != 0) {
- sample->set_stack_trace_id(stack_trace_id);
- sample->set_stack_trace_hash(stack_trace_hash);
+ const unsigned int stacktrace_hash = stacktrace->hash();
+ if (stacktrace_hash != 0) {
+ sample->set_stack_trace_id(stacktrace_id(stacktrace, thread));
+ sample->set_stack_trace_hash(stacktrace_hash);
}
sample->set_span(allocated);
@@ -118,6 +206,53 @@
_priority_queue->push(sample);
}
+void ObjectSampler::scavenge() {
+ ObjectSample* current = _list->last();
+ while (current != NULL) {
+ ObjectSample* next = current->next();
+ if (current->is_dead()) {
+ remove_dead(current);
+ }
+ current = next;
+ }
+ _dead_samples = false;
+}
+
+void ObjectSampler::remove_dead(ObjectSample* sample) {
+ assert(sample != NULL, "invariant");
+ assert(sample->is_dead(), "invariant");
+ ObjectSample* const previous = sample->prev();
+ // push span on to previous
+ if (previous != NULL) {
+ _priority_queue->remove(previous);
+ previous->add_span(sample->span());
+ _priority_queue->push(previous);
+ }
+ _priority_queue->remove(sample);
+ _list->release(sample);
+}
+
+void ObjectSampler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
+ assert(is_created(), "invariant");
+ assert(SafepointSynchronize::is_at_safepoint(), "invariant");
+ ObjectSampler& sampler = instance();
+ ObjectSample* current = sampler._list->last();
+ while (current != NULL) {
+ ObjectSample* next = current->next();
+ if (!current->is_dead()) {
+ if (is_alive->do_object_b(current->object())) {
+ // The weakly referenced object is alive, update pointer
+ f->do_oop(const_cast<oop*>(current->object_addr()));
+ } else {
+ current->set_dead();
+ sampler._dead_samples = true;
+ }
+ }
+ current = next;
+ }
+ sampler._last_sweep = JfrTicks::now();
+}
+
const ObjectSample* ObjectSampler::last() const {
return _list->last();
}
@@ -134,50 +269,6 @@
_list->set_last_resolved(sample);
}
-void ObjectSampler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
- ObjectSample* current = _list->last();
- while (current != NULL) {
- ObjectSample* next = current->next();
- if (!current->is_dead()) {
- if (is_alive->do_object_b(current->object())) {
- // The weakly referenced object is alive, update pointer
- f->do_oop(const_cast<oop*>(current->object_addr()));
- } else {
- current->set_dead();
- _dead_samples = true;
- }
- }
- current = next;
- }
- _last_sweep = JfrTicks::now();
-}
-
-void ObjectSampler::remove_dead(ObjectSample* sample) {
- assert(sample != NULL, "invariant");
- assert(sample->is_dead(), "invariant");
- ObjectSample* const previous = sample->prev();
- // push span on to previous
- if (previous != NULL) {
- _priority_queue->remove(previous);
- previous->add_span(sample->span());
- _priority_queue->push(previous);
- }
- _priority_queue->remove(sample);
- _list->release(sample);
-}
-
-void ObjectSampler::scavenge() {
- ObjectSample* current = _list->last();
- while (current != NULL) {
- ObjectSample* next = current->next();
- if (current->is_dead()) {
- remove_dead(current);
- }
- current = next;
- }
- _dead_samples = false;
-}
-
int ObjectSampler::item_count() const {
return _priority_queue->count();
}
@@ -189,7 +280,7 @@
ObjectSample* ObjectSampler::item_at(int index) {
return const_cast<ObjectSample*>(
const_cast<const ObjectSampler*>(this)->item_at(index)
- );
+ );
}
const JfrTicks& ObjectSampler::last_sweep() const {
--- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -28,7 +28,10 @@
#include "memory/allocation.hpp"
#include "jfr/utilities/jfrTime.hpp"
+typedef u8 traceid;
+
class BoolObjectClosure;
+class JfrStackTrace;
class OopClosure;
class ObjectSample;
class ObjectSampler;
@@ -40,11 +43,13 @@
// making sure the samples are evenly distributed as
// new entries are added and removed.
class ObjectSampler : public CHeapObj<mtTracing> {
+ friend class EventEmitter;
+ friend class JfrRecorderService;
friend class LeakProfiler;
- friend class ObjectSampleCheckpoint;
friend class StartOperation;
friend class StopOperation;
- friend class EmitEventOperation;
+ friend class ObjectSampleCheckpoint;
+ friend class WriteObjectSampleStacktrace;
private:
SamplePriorityQueue* _priority_queue;
SampleList* _list;
@@ -52,20 +57,33 @@
size_t _total_allocated;
size_t _threshold;
size_t _size;
- volatile int _tryLock;
bool _dead_samples;
+ // Lifecycle
explicit ObjectSampler(size_t size);
~ObjectSampler();
+ static bool create(size_t size);
+ static bool is_created();
+ static ObjectSampler* sampler();
+ static void destroy();
- void add(HeapWord* object, size_t size, JavaThread* thread);
+ // For operations that require exclusive access (non-safepoint)
+ static ObjectSampler* acquire();
+ static void release();
+
+ // Stacktrace
+ static void fill_stacktrace(JfrStackTrace* stacktrace, JavaThread* thread);
+ traceid stacktrace_id(const JfrStackTrace* stacktrace, JavaThread* thread);
+
+ // Sampling
+ static void sample(HeapWord* object, size_t size, JavaThread* thread);
+ void add(HeapWord* object, size_t size, traceid thread_id, JfrStackTrace* stacktrace, JavaThread* thread);
+ void scavenge();
void remove_dead(ObjectSample* sample);
- void scavenge();
// Called by GC
- void oops_do(BoolObjectClosure* is_alive, OopClosure* f);
+ static void oops_do(BoolObjectClosure* is_alive, OopClosure* f);
- public:
const ObjectSample* item_at(int index) const;
ObjectSample* item_at(int index);
int item_count() const;
--- a/src/hotspot/share/jfr/leakprofiler/startOperation.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/startOperation.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,35 +25,18 @@
#ifndef SHARE_JFR_LEAKPROFILER_STARTOPERATION_HPP
#define SHARE_JFR_LEAKPROFILER_STARTOPERATION_HPP
-#include "jfr/recorder/jfrRecorder.hpp"
-#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
-#include "jfr/recorder/service/jfrOptionSet.hpp"
-#include "logging/log.hpp"
-#include "runtime/vmOperations.hpp"
+#include "jfr/leakprofiler/utilities/vmOperation.hpp"
-// Safepoint operation for starting leak profiler object sampler
-class StartOperation : public VM_Operation {
+// Safepoint operation for creating and starting the leak profiler object sampler
+class StartOperation : public OldObjectVMOperation {
private:
- jlong _sample_count;
+ int _sample_count;
public:
- StartOperation(jlong sample_count) :
- _sample_count(sample_count) {
- }
-
- Mode evaluation_mode() const {
- return _safepoint;
- }
-
- VMOp_Type type() const {
- return VMOp_GC_HeapInspection;
- }
+ StartOperation(int sample_count) : _sample_count(sample_count) {}
virtual void doit() {
- assert(!LeakProfiler::is_running(), "invariant");
- jint queue_size = JfrOptionSet::old_object_queue_size();
- LeakProfiler::set_object_sampler(new ObjectSampler(queue_size));
- log_trace(jfr, system)( "Object sampling started");
+ ObjectSampler::create(_sample_count);
}
};
--- a/src/hotspot/share/jfr/leakprofiler/stopOperation.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/stopOperation.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,31 +25,14 @@
#ifndef SHARE_JFR_LEAKPROFILER_STOPOPERATION_HPP
#define SHARE_JFR_LEAKPROFILER_STOPOPERATION_HPP
-#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
-#include "jfr/recorder/service/jfrOptionSet.hpp"
-#include "logging/log.hpp"
-#include "runtime/vmOperations.hpp"
-
-// Safepoint operation for stopping leak profiler object sampler
-class StopOperation : public VM_Operation {
- public:
- StopOperation() {}
+#include "jfr/leakprofiler/utilities/vmOperation.hpp"
- Mode evaluation_mode() const {
- return _safepoint;
- }
-
- VMOp_Type type() const {
- return VMOp_GC_HeapInspection;
- }
-
+// Safepoint operation for stopping and destroying the leak profiler object sampler
+class StopOperation : public OldObjectVMOperation {
+ public:
virtual void doit() {
- assert(LeakProfiler::is_running(), "invariant");
- ObjectSampler* object_sampler = LeakProfiler::object_sampler();
- delete object_sampler;
- LeakProfiler::set_object_sampler(NULL);
- log_trace(jfr, system)( "Object sampling stopped");
+ ObjectSampler::destroy();
}
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jfr/leakprofiler/utilities/vmOperation.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_JFR_LEAKPROFILER_UTILITIES_VMOPERATION_HPP
+#define SHARE_JFR_LEAKPROFILER_UTILITIES_VMOPERATION_HPP
+
+#include "runtime/vmOperations.hpp"
+
+class OldObjectVMOperation : public VM_Operation {
+ public:
+ Mode evaluation_mode() const {
+ return _safepoint;
+ }
+
+ VMOp_Type type() const {
+ return VMOp_JFROldObject;
+ }
+};
+
+#endif // SHARE_JFR_LEAKPROFILER_UTILITIES_VMOPERATION_HPP
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -311,7 +311,7 @@
if (LeakProfiler::is_running()) {
JfrCheckpointWriter leakp_writer(false, true, Thread::current());
type_set.write(writer, &leakp_writer);
- ObjectSampleCheckpoint::install(leakp_writer, true, true);
+ ObjectSampleCheckpoint::install(leakp_writer, true);
return;
}
type_set.write(writer, NULL);
@@ -319,10 +319,10 @@
void TypeSet::serialize(JfrCheckpointWriter& writer) {
TypeSetSerialization type_set(false);
- if (LeakProfiler::is_suspended()) {
+ if (LeakProfiler::is_running()) {
JfrCheckpointWriter leakp_writer(false, true, Thread::current());
type_set.write(writer, &leakp_writer);
- ObjectSampleCheckpoint::install(leakp_writer, false, true);
+ ObjectSampleCheckpoint::install(leakp_writer, false);
return;
}
type_set.write(writer, NULL);
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -194,9 +194,6 @@
if (!validate_recording_options(thread)) {
return false;
}
- if (!JfrJavaEventWriter::initialize()) {
- return false;
- }
if (!JfrOptionSet::configure(thread)) {
return false;
}
@@ -246,6 +243,9 @@
ResourceMark rm;
HandleMark hm;
+ if (!create_java_event_writer()) {
+ return false;
+ }
if (!create_jvmti_agent()) {
return false;
}
@@ -287,6 +287,10 @@
static JfrOSInterface* _os_interface = NULL;
static JfrThreadSampling* _thread_sampling = NULL;
+bool JfrRecorder::create_java_event_writer() {
+ return JfrJavaEventWriter::initialize();
+}
+
bool JfrRecorder::create_jvmti_agent() {
return JfrOptionSet::allow_retransforms() ? JfrJvmtiAgent::create() : true;
}
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -40,6 +40,7 @@
private:
static bool create_checkpoint_manager();
static bool create_chunk_repository();
+ static bool create_java_event_writer();
static bool create_jvmti_agent();
static bool create_os_interface();
static bool create_post_box();
--- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -24,7 +24,9 @@
#include "precompiled.hpp"
#include "jfr/jni/jfrJavaSupport.hpp"
+#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
+#include "jfr/leakprofiler/sampling/objectSampler.hpp"
#include "jfr/recorder/jfrRecorder.hpp"
#include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
#include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp"
@@ -335,6 +337,7 @@
open_new_chunk(true);
}
_checkpoint_manager.register_service_thread(Thread::current());
+ JfrMetadataEvent::lock();
}
void JfrRecorderService::open_new_chunk(bool vm_error) {
@@ -398,6 +401,11 @@
write_stack_trace_checkpoint.process();
}
+static void write_object_sample_stacktrace(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repository) {
+ WriteObjectSampleStacktrace object_sample_stacktrace(sampler, stack_trace_repository);
+ object_sample_stacktrace.process();
+}
+
static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
WriteStringPool write_string_pool(string_pool);
WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool);
@@ -418,8 +426,9 @@
// write checkpoint epoch transition list->
// write stack trace checkpoint ->
// write string pool checkpoint ->
-// write storage ->
-// release stream lock
+// write object sample stacktraces ->
+// write storage ->
+// release stream lock
//
void JfrRecorderService::pre_safepoint_write() {
MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
@@ -428,6 +437,13 @@
_checkpoint_manager.write_epoch_transition_mspace();
write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false);
write_stringpool_checkpoint(_string_pool, _chunkwriter);
+ if (LeakProfiler::is_running()) {
+ // Exclusive access to the object sampler instance.
+ // The sampler is released (unlocked) later in post_safepoint_write.
+ ObjectSampler* const sampler = ObjectSampler::acquire();
+ assert(sampler != NULL, "invariant");
+ write_object_sample_stacktrace(sampler, _stack_trace_repository);
+ }
_storage.write();
}
@@ -436,16 +452,10 @@
VMThread::execute(&safepoint_task);
}
-static void write_object_sample_stacktrace(JfrStackTraceRepository& stack_trace_repository) {
- WriteObjectSampleStacktrace object_sample_stacktrace(stack_trace_repository);
- object_sample_stacktrace.process();
-}
-
//
// safepoint write sequence
//
// lock stream lock ->
-// write object sample stacktraces ->
// write stacktrace repository ->
// write string pool ->
// write safepoint dependent types ->
@@ -458,7 +468,6 @@
void JfrRecorderService::safepoint_write() {
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
- write_object_sample_stacktrace(_stack_trace_repository);
write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true);
write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter);
_checkpoint_manager.write_safepoint_types();
@@ -478,13 +487,14 @@
//
// post-safepoint write sequence
//
-// lock stream lock ->
-// write type set ->
-// write checkpoints ->
-// write metadata event ->
-// write chunk header ->
-// close chunk fd ->
-// release stream lock
+// write type set ->
+// release object sampler ->
+// lock stream lock ->
+// write checkpoints ->
+// write metadata event ->
+// write chunk header ->
+// close chunk fd ->
+// release stream lock
//
void JfrRecorderService::post_safepoint_write() {
assert(_chunkwriter.is_valid(), "invariant");
@@ -493,6 +503,11 @@
// already tagged artifacts for the previous epoch. We can accomplish this concurrently
// with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint.
_checkpoint_manager.write_type_set();
+ if (LeakProfiler::is_running()) {
+ // The object sampler instance was exclusively acquired and locked in pre_safepoint_write.
+ // Note: There is a dependency on write_type_set() above, ensure the release is subsequent.
+ ObjectSampler::release();
+ }
MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
// serialize any outstanding checkpoint memory
_checkpoint_manager.write();
@@ -512,11 +527,9 @@
void JfrRecorderService::finalize_current_chunk_on_vm_error() {
assert(_chunkwriter.is_valid(), "invariant");
pre_safepoint_write();
- JfrMetadataEvent::lock();
// Do not attempt safepoint dependent operations during emergency dump.
// Optimistically write tagged artifacts.
_checkpoint_manager.shift_epoch();
- _checkpoint_manager.write_type_set();
// update time
_chunkwriter.time_stamp_chunk_now();
post_safepoint_write();
--- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -164,7 +164,13 @@
}
traceid JfrStackTraceRepository::add(const JfrStackTrace& stacktrace) {
- return instance().add_trace(stacktrace);
+ traceid tid = instance().add_trace(stacktrace);
+ if (tid == 0) {
+ stacktrace.resolve_linenos();
+ tid = instance().add_trace(stacktrace);
+ }
+ assert(tid != 0, "invariant");
+ return tid;
}
traceid JfrStackTraceRepository::record(Thread* thread, int skip /* 0 */) {
@@ -187,54 +193,29 @@
return instance().record_for((JavaThread*)thread, skip,frames, tl->stackdepth());
}
-traceid JfrStackTraceRepository::record(Thread* thread, int skip, unsigned int* hash) {
- assert(thread == Thread::current(), "invariant");
- JfrThreadLocal* const tl = thread->jfr_thread_local();
- assert(tl != NULL, "invariant");
-
- if (tl->has_cached_stack_trace()) {
- *hash = tl->cached_stack_trace_hash();
- return tl->cached_stack_trace_id();
- }
- if (!thread->is_Java_thread() || thread->is_hidden_from_external_view()) {
- return 0;
- }
- JfrStackFrame* frames = tl->stackframes();
- if (frames == NULL) {
- // pending oom
- return 0;
- }
- assert(frames != NULL, "invariant");
- assert(tl->stackframes() == frames, "invariant");
- return instance().record_for((JavaThread*)thread, skip, frames, tl->stackdepth(), hash);
-}
-
traceid JfrStackTraceRepository::record_for(JavaThread* thread, int skip, JfrStackFrame *frames, u4 max_frames) {
JfrStackTrace stacktrace(frames, max_frames);
- if (!stacktrace.record_safe(thread, skip)) {
- return 0;
- }
- traceid tid = add(stacktrace);
- if (tid == 0) {
- stacktrace.resolve_linenos();
- tid = add(stacktrace);
- }
- return tid;
+ return stacktrace.record_safe(thread, skip) ? add(stacktrace) : 0;
+}
+
+traceid JfrStackTraceRepository::add(const JfrStackTrace* stacktrace, JavaThread* thread) {
+ assert(stacktrace != NULL, "invariant");
+ assert(thread != NULL, "invariant");
+ assert(stacktrace->hash() != 0, "invariant");
+ return add(*stacktrace);
}
-traceid JfrStackTraceRepository::record_for(JavaThread* thread, int skip, JfrStackFrame *frames, u4 max_frames, unsigned int* hash) {
- assert(hash != NULL && *hash == 0, "invariant");
- JfrStackTrace stacktrace(frames, max_frames);
- if (!stacktrace.record_safe(thread, skip, true)) {
- return 0;
+bool JfrStackTraceRepository::fill_stacktrace_for(JavaThread* thread, JfrStackTrace* stacktrace, int skip) {
+ assert(thread == Thread::current(), "invariant");
+ assert(stacktrace != NULL, "invariant");
+ JfrThreadLocal* const tl = thread->jfr_thread_local();
+ assert(tl != NULL, "invariant");
+ const unsigned int cached_stacktrace_hash = tl->cached_stack_trace_hash();
+ if (cached_stacktrace_hash != 0) {
+ stacktrace->set_hash(cached_stacktrace_hash);
+ return true;
}
- traceid tid = add(stacktrace);
- if (tid == 0) {
- stacktrace.resolve_linenos();
- tid = add(stacktrace);
- }
- *hash = stacktrace._hash;
- return tid;
+ return stacktrace->record_safe(thread, skip, true);
}
size_t JfrStackTraceRepository::write_impl(JfrChunkWriter& sw, bool clear) {
@@ -363,7 +344,7 @@
return trace;
}
-void JfrStackFrame::resolve_lineno() {
+void JfrStackFrame::resolve_lineno() const {
assert(_method, "no method pointer");
assert(_line == 0, "already have linenumber");
_line = _method->line_number_from_bci(_bci);
@@ -375,7 +356,7 @@
_frames[frame_pos] = frame;
}
-void JfrStackTrace::resolve_linenos() {
+void JfrStackTrace::resolve_linenos() const {
for(unsigned int i = 0; i < _nr_of_frames; i++) {
_frames[i].resolve_lineno();
}
--- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -36,9 +36,9 @@
class JfrStackFrame {
private:
- const Method* _method;
+ mutable const Method* _method;
traceid _methodid;
- int _line;
+ mutable int _line;
int _bci;
u1 _type;
@@ -58,7 +58,7 @@
bool equals(const JfrStackFrame& rhs) const;
void write(JfrChunkWriter& cw) const;
void write(JfrCheckpointWriter& cpw) const;
- void resolve_lineno();
+ void resolve_lineno() const;
};
class JfrStackTrace : public StackObj {
@@ -70,7 +70,7 @@
unsigned int _hash;
const u4 _max_frames;
bool _reached_root;
- bool _lineno;
+ mutable bool _lineno;
public:
JfrStackTrace(JfrStackFrame* frames, u4 max_frames) : _frames(frames),
@@ -82,9 +82,10 @@
_lineno(false) {}
bool record_thread(JavaThread& thread, frame& frame);
bool record_safe(JavaThread* thread, int skip, bool leakp = false);
- void resolve_linenos();
+ void resolve_linenos() const;
void set_nr_of_frames(u4 nr_of_frames) { _nr_of_frames = nr_of_frames; }
void set_hash(unsigned int hash) { _hash = hash; }
+ unsigned int hash() const { return _hash; }
void set_frame(u4 frame_pos, JfrStackFrame& frame);
void set_reached_root(bool reached_root) { _reached_root = reached_root; }
bool full_stacktrace() const { return _reached_root; }
@@ -128,23 +129,26 @@
traceid _next_id;
u4 _entries;
- size_t write_impl(JfrChunkWriter& cw, bool clear);
+ traceid add_trace(const JfrStackTrace& stacktrace);
+ static traceid add(const JfrStackTrace* stacktrace, JavaThread* thread);
traceid record_for(JavaThread* thread, int skip, JfrStackFrame* frames, u4 max_frames);
- traceid record_for(JavaThread* thread, int skip, JfrStackFrame* frames, u4 max_frames, unsigned int* hash);
- traceid add_trace(const JfrStackTrace& stacktrace);
+
+ size_t write_impl(JfrChunkWriter& cw, bool clear);
const StackTrace* resolve_entry(unsigned int hash, traceid id) const;
-
static void write_metadata(JfrCheckpointWriter& cpw);
+ static bool fill_stacktrace_for(JavaThread* thread, JfrStackTrace* stacktrace, int skip);
+
JfrStackTraceRepository();
- static JfrStackTraceRepository& instance();
- public:
static JfrStackTraceRepository* create();
bool initialize();
static void destroy();
+
+ static JfrStackTraceRepository& instance();
+
+ public:
static traceid add(const JfrStackTrace& stacktrace);
static traceid record(Thread* thread, int skip = 0);
- static traceid record(Thread* thread, int skip, unsigned int* hash);
traceid write(JfrCheckpointWriter& cpw, traceid id, unsigned int hash);
size_t write(JfrChunkWriter& cw, bool clear);
size_t clear();
--- a/src/hotspot/share/jfr/support/jfrFlush.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/support/jfrFlush.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -48,10 +48,12 @@
template <typename Event>
class JfrConditionalFlush {
+ protected:
+ bool _enabled;
public:
typedef JfrBuffer Type;
- JfrConditionalFlush(Thread* t) {
- if (jfr_is_event_enabled(Event::eventId)) {
+ JfrConditionalFlush(Thread* t) : _enabled(jfr_is_event_enabled(Event::eventId)) {
+ if (_enabled) {
jfr_conditional_flush(Event::eventId, sizeof(Event), t);
}
}
@@ -63,7 +65,7 @@
bool _owner;
public:
JfrConditionalFlushWithStacktrace(Thread* t) : JfrConditionalFlush<Event>(t), _t(t), _owner(false) {
- if (Event::has_stacktrace() && jfr_has_stacktrace_enabled(Event::eventId)) {
+ if (this->_enabled && Event::has_stacktrace() && jfr_has_stacktrace_enabled(Event::eventId)) {
_owner = jfr_save_stacktrace(t);
}
}
--- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -150,9 +150,7 @@
JfrStackFrame* JfrThreadLocal::install_stackframes() const {
assert(_stackframes == NULL, "invariant");
- _stackdepth = (u4)JfrOptionSet::stackdepth();
- guarantee(_stackdepth > 0, "Stackdepth must be > 0");
- _stackframes = NEW_C_HEAP_ARRAY(JfrStackFrame, _stackdepth, mtTracing);
+ _stackframes = NEW_C_HEAP_ARRAY(JfrStackFrame, stackdepth(), mtTracing);
return _stackframes;
}
@@ -163,3 +161,7 @@
ByteSize JfrThreadLocal::java_event_writer_offset() {
return in_ByteSize(offset_of(JfrThreadLocal, _java_event_writer));
}
+
+u4 JfrThreadLocal::stackdepth() const {
+ return _stackdepth != 0 ? _stackdepth : (u4)JfrOptionSet::stackdepth();
+}
--- a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -113,9 +113,7 @@
_stackframes = frames;
}
- u4 stackdepth() const {
- return _stackdepth;
- }
+ u4 stackdepth() const;
void set_stackdepth(u4 depth) {
_stackdepth = depth;
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -135,8 +135,7 @@
bool JfrJavaEventWriter::initialize() {
static bool initialized = false;
if (!initialized) {
- Thread* thread = Thread::current();
- initialized = setup_event_writer_offsets(thread);
+ initialized = setup_event_writer_offsets(Thread::current());
}
return initialized;
}
@@ -155,6 +154,7 @@
// large enough to accommodate the "requested size".
const bool is_valid = buffer->free_size() >= (size_t)(used + requested);
u1* const new_current_position = is_valid ? buffer->pos() + used : buffer->pos();
+ assert(start_pos_offset != invalid_offset, "invariant");
w->long_field_put(start_pos_offset, (jlong)buffer->pos());
w->long_field_put(current_pos_offset, (jlong)new_current_position);
// only update java writer if underlying memory changed
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -33,13 +33,14 @@
class JfrJavaEventWriter : AllStatic {
friend class JfrCheckpointThreadClosure;
+ friend class JfrJavaEventWriterNotificationClosure;
friend class JfrJavaEventWriterNotifyOperation;
- friend class JfrJavaEventWriterNotificationClosure;
+ friend class JfrRecorder;
private:
+ static bool initialize();
static void notify(JavaThread* jt);
public:
- static bool initialize();
static void notify();
static jobject event_writer(Thread* t);
static jobject new_event_writer(TRAPS);
--- a/src/hotspot/share/jvmci/jvmci.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmci.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
-#include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorage.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
@@ -58,9 +58,7 @@
}
void JVMCI::initialize_globals() {
- _object_handles = new OopStorage("JVMCI Global Oop Handles",
- JVMCIGlobalAlloc_lock,
- JVMCIGlobalActive_lock);
+ _object_handles = SystemDictionary::vm_global_oop_storage();
_metadata_handles = MetadataHandleBlock::allocate_block();
if (UseJVMCINativeLibrary) {
// There are two runtimes.
@@ -115,12 +113,6 @@
_metadata_handles->chain_free_list(handle);
}
-void JVMCI::oops_do(OopClosure* f) {
- if (_object_handles != NULL) {
- _object_handles->oops_do(f);
- }
-}
-
void JVMCI::metadata_do(void f(Metadata*)) {
if (_metadata_handles != NULL) {
_metadata_handles->metadata_do(f);
--- a/src/hotspot/share/jvmci/jvmci.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmci.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -74,8 +74,6 @@
static void metadata_do(void f(Metadata*));
- static void oops_do(OopClosure* f);
-
static void shutdown();
static bool shutdown_called();
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -36,9 +36,8 @@
#include "jvmci/jniAccessMark.inline.hpp"
#include "jvmci/jvmciRuntime.hpp"
-JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter):
+JVMCICompileState::JVMCICompileState(CompileTask* task):
_task(task),
- _system_dictionary_modification_counter(system_dictionary_modification_counter),
_retryable(true),
_failure_reason(NULL),
_failure_reason_on_C_heap(false) {
--- a/src/hotspot/share/jvmci/jvmciEnv.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciEnv.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -90,7 +90,6 @@
friend class JVMCIVMStructs;
private:
CompileTask* _task;
- int _system_dictionary_modification_counter;
// Cache JVMTI state. Defined as bytes so that reading them from Java
// via Unsafe is well defined (the C++ type for bool is implementation
@@ -109,11 +108,10 @@
bool _failure_reason_on_C_heap;
public:
- JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter);
+ JVMCICompileState(CompileTask* task);
CompileTask* task() { return _task; }
- int system_dictionary_modification_counter() { return _system_dictionary_modification_counter; }
bool jvmti_state_changed() const;
bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; }
bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; }
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1327,14 +1327,13 @@
// Dependencies must be checked when the system dictionary changes
// or if we don't know whether it has changed (i.e., compile_state == NULL).
- bool counter_changed = compile_state == NULL || compile_state->system_dictionary_modification_counter() != SystemDictionary::number_of_modifications();
CompileTask* task = compile_state == NULL ? NULL : compile_state->task();
- Dependencies::DepType result = dependencies->validate_dependencies(task, counter_changed, failure_detail);
+ Dependencies::DepType result = dependencies->validate_dependencies(task, failure_detail);
if (result == Dependencies::end_marker) {
return JVMCI::ok;
}
- if (!Dependencies::is_klass_type(result) || counter_changed) {
+ if (!Dependencies::is_klass_type(result) || compile_state == NULL) {
return JVMCI::dependencies_failed;
}
// The dependencies were invalid at the time of installation
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -173,6 +173,7 @@
volatile_nonstatic_field(JavaThread, _exception_oop, oop) \
volatile_nonstatic_field(JavaThread, _exception_pc, address) \
volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \
+ volatile_nonstatic_field(JavaThread, _doing_unsafe_access, bool) \
nonstatic_field(JavaThread, _osthread, OSThread*) \
nonstatic_field(JavaThread, _pending_deoptimization, int) \
nonstatic_field(JavaThread, _pending_failed_speculation, jlong) \
--- a/src/hotspot/share/libadt/set.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/libadt/set.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -43,7 +43,6 @@
// The caller must deallocate the string.
char *Set::setstr() const
{
- if( this == NULL ) return os::strdup("{no set}");
Set &set = clone(); // Virtually copy the basic set.
set.Sort(); // Sort elements for in-order retrieval
--- a/src/hotspot/share/logging/logDecorations.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/logging/logDecorations.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,14 @@
#include "jvm.h"
#include "logging/logConfiguration.hpp"
#include "logging/logDecorations.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/thread.inline.hpp"
#include "services/management.hpp"
jlong LogDecorations::_vm_start_time_millis = 0;
-const char* LogDecorations::_host_name = "";
+const char* volatile LogDecorations::_host_name = NULL;
LogDecorations::LogDecorations(LogLevelType level, const LogTagSet &tagset, const LogDecorators &decorators)
: _level(level), _tagset(tagset), _millis(-1) {
@@ -38,11 +40,23 @@
}
void LogDecorations::initialize(jlong vm_start_time) {
- char buffer[1024];
- if (os::get_host_name(buffer, sizeof(buffer))){
- _host_name = os::strdup_check_oom(buffer);
+ _vm_start_time_millis = vm_start_time;
+}
+
+const char* LogDecorations::host_name() {
+ const char* host_name = OrderAccess::load_acquire(&_host_name);
+ if (host_name == NULL) {
+ char buffer[1024];
+ if (os::get_host_name(buffer, sizeof(buffer))) {
+ host_name = os::strdup_check_oom(buffer);
+ const char* old_value = Atomic::cmpxchg(host_name, &_host_name, (const char*)NULL);
+ if (old_value != NULL) {
+ os::free((void *) host_name);
+ host_name = old_value;
+ }
+ }
}
- _vm_start_time_millis = vm_start_time;
+ return host_name;
}
void LogDecorations::create_decorations(const LogDecorators &decorators) {
@@ -128,7 +142,7 @@
}
char* LogDecorations::create_hostname_decoration(char* pos) {
- int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), "%s", _host_name);
+ int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), "%s", host_name());
ASSERT_AND_RETURN(written, pos)
}
--- a/src/hotspot/share/logging/logDecorations.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/logging/logDecorations.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -38,8 +38,9 @@
const LogTagSet& _tagset;
jlong _millis;
static jlong _vm_start_time_millis;
- static const char* _host_name;
+ static const char* volatile _host_name;
+ const char* host_name();
jlong java_millis();
void create_decorations(const LogDecorators& decorators);
--- a/src/hotspot/share/memory/allocation.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/allocation.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -259,25 +259,6 @@
st->print("AllocatedObj(" INTPTR_FORMAT ")", p2i(this));
}
-AllocStats::AllocStats() {
- start_mallocs = os::num_mallocs;
- start_frees = os::num_frees;
- start_malloc_bytes = os::alloc_bytes;
- start_mfree_bytes = os::free_bytes;
- start_res_bytes = Arena::_bytes_allocated;
-}
-
-julong AllocStats::num_mallocs() { return os::num_mallocs - start_mallocs; }
-julong AllocStats::alloc_bytes() { return os::alloc_bytes - start_malloc_bytes; }
-julong AllocStats::num_frees() { return os::num_frees - start_frees; }
-julong AllocStats::free_bytes() { return os::free_bytes - start_mfree_bytes; }
-julong AllocStats::resource_bytes() { return Arena::_bytes_allocated - start_res_bytes; }
-void AllocStats::print() {
- tty->print_cr(UINT64_FORMAT " mallocs (" UINT64_FORMAT "MB), "
- UINT64_FORMAT " frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc",
- num_mallocs(), alloc_bytes()/M, num_frees(), free_bytes()/M, resource_bytes()/M);
-}
-
ReallocMark::ReallocMark() {
#ifdef ASSERT
Thread *thread = Thread::current();
--- a/src/hotspot/share/memory/allocation.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/allocation.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -507,23 +507,6 @@
#define FREE_C_HEAP_OBJ(objname)\
FreeHeap((char*)objname);
-// for statistics
-#ifndef PRODUCT
-class AllocStats : StackObj {
- julong start_mallocs, start_frees;
- julong start_malloc_bytes, start_mfree_bytes, start_res_bytes;
- public:
- AllocStats();
-
- julong num_mallocs(); // since creation of receiver
- julong alloc_bytes();
- julong num_frees();
- julong free_bytes();
- julong resource_bytes();
- void print();
-};
-#endif
-
//------------------------------ReallocMark---------------------------------
// Code which uses REALLOC_RESOURCE_ARRAY should check an associated
--- a/src/hotspot/share/memory/allocation.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/allocation.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -34,16 +34,13 @@
// Explicit C-heap memory management
#ifndef PRODUCT
-// Increments unsigned long value for statistics (not atomic on MP).
+// Increments unsigned long value for statistics (not atomic on MP, but avoids word-tearing on 32 bit).
inline void inc_stat_counter(volatile julong* dest, julong add_value) {
-#if defined(SPARC) || defined(X86)
- // Sparc and X86 have atomic jlong (8 bytes) instructions
+#ifdef _LP64
+ *dest += add_value;
+#else
julong value = Atomic::load(dest);
- value += add_value;
- Atomic::store(value, dest);
-#else
- // possible word-tearing during load/store
- *dest += add_value;
+ Atomic::store(value + add_value, dest);
#endif
}
#endif
--- a/src/hotspot/share/memory/arena.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/arena.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -475,10 +475,6 @@
#ifndef PRODUCT
-julong Arena::_bytes_allocated = 0;
-
-void Arena::inc_bytes_allocated(size_t x) { inc_stat_counter(&_bytes_allocated, x); }
-
// debugging code
inline void Arena::free_all(char** start, char** end) {
for (char** p = start; p < end; p++) if (*p) os::free(*p);
--- a/src/hotspot/share/memory/arena.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/arena.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -106,11 +106,8 @@
void* grow(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
size_t _size_in_bytes; // Size of arena (used for native memory tracking)
- NOT_PRODUCT(static julong _bytes_allocated;) // total #bytes allocated since start
- friend class AllocStats;
debug_only(void* malloc(size_t size);)
debug_only(void* internal_malloc_4(size_t x);)
- NOT_PRODUCT(void inc_bytes_allocated(size_t x);)
void signal_out_of_memory(size_t request, const char* whence) const;
@@ -148,7 +145,6 @@
debug_only(if (UseMallocOnly) return malloc(x);)
if (!check_for_overflow(x, "Arena::Amalloc", alloc_failmode))
return NULL;
- NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode);
} else {
@@ -163,7 +159,6 @@
debug_only(if (UseMallocOnly) return malloc(x);)
if (!check_for_overflow(x, "Arena::Amalloc_4", alloc_failmode))
return NULL;
- NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode);
} else {
@@ -185,7 +180,6 @@
#endif
if (!check_for_overflow(x, "Arena::Amalloc_D", alloc_failmode))
return NULL;
- NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode); // grow() returns a result aligned >= 8 bytes.
} else {
--- a/src/hotspot/share/memory/filemap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/filemap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -155,6 +155,8 @@
const char *vm_version = VM_Version::internal_vm_info_string();
const int version_len = (int)strlen(vm_version);
+ memset(header_version, 0, JVM_IDENT_MAX);
+
if (version_len < (JVM_IDENT_MAX-1)) {
strcpy(header_version, vm_version);
@@ -170,6 +172,8 @@
sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash);
header_version[JVM_IDENT_MAX-1] = 0; // Null terminate.
}
+
+ assert(header_version[JVM_IDENT_MAX-1] == 0, "must be");
}
FileMapInfo::FileMapInfo(bool is_static) {
@@ -891,10 +895,59 @@
fail_continue("Unable to read the file header.");
return false;
}
+
+ if (!Arguments::has_jimage()) {
+ FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build.");
+ return false;
+ }
+
+ unsigned int expected_magic = is_static ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC;
+ if (_header->_magic != expected_magic) {
+ log_info(cds)("_magic expected: 0x%08x", expected_magic);
+ log_info(cds)(" actual: 0x%08x", _header->_magic);
+ FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
+ return false;
+ }
+
if (_header->_version != CURRENT_CDS_ARCHIVE_VERSION) {
+ log_info(cds)("_version expected: %d", CURRENT_CDS_ARCHIVE_VERSION);
+ log_info(cds)(" actual: %d", _header->_version);
fail_continue("The shared archive file has the wrong version.");
return false;
}
+
+ if (_header->_header_size != sz) {
+ log_info(cds)("_header_size expected: " SIZE_FORMAT, sz);
+ log_info(cds)(" actual: " SIZE_FORMAT, _header->_header_size);
+ FileMapInfo::fail_continue("The shared archive file has an incorrect header size.");
+ return false;
+ }
+
+ if (_header->_jvm_ident[JVM_IDENT_MAX-1] != 0) {
+ FileMapInfo::fail_continue("JVM version identifier is corrupted.");
+ return false;
+ }
+
+ char header_version[JVM_IDENT_MAX];
+ get_header_version(header_version);
+ if (strncmp(_header->_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
+ log_info(cds)("_jvm_ident expected: %s", header_version);
+ log_info(cds)(" actual: %s", _header->_jvm_ident);
+ FileMapInfo::fail_continue("The shared archive file was created by a different"
+ " version or build of HotSpot");
+ return false;
+ }
+
+ if (VerifySharedSpaces) {
+ int expected_crc = _header->compute_crc();
+ if (expected_crc != _header->_crc) {
+ log_info(cds)("_crc expected: %d", expected_crc);
+ log_info(cds)(" actual: %d", _header->_crc);
+ FileMapInfo::fail_continue("Header checksum verification failed.");
+ return false;
+ }
+ }
+
_file_offset = n;
size_t info_size = _header->_paths_misc_info_size;
@@ -909,10 +962,6 @@
_file_offset += n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name
if (is_static) {
- if (_header->_magic != CDS_ARCHIVE_MAGIC) {
- fail_continue("Incorrect static archive magic number");
- return false;
- }
// just checking the last region is sufficient since the archive is written
// in sequential order
size_t len = lseek(fd, 0, SEEK_END);
@@ -1750,33 +1799,7 @@
// This function should only be called during run time with UseSharedSpaces enabled.
bool FileMapHeader::validate() {
- if (VerifySharedSpaces && compute_crc() != _crc) {
- FileMapInfo::fail_continue("Header checksum verification failed.");
- return false;
- }
- if (!Arguments::has_jimage()) {
- FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build.");
- return false;
- }
-
- if (_version != CURRENT_CDS_ARCHIVE_VERSION) {
- FileMapInfo::fail_continue("The shared archive file is the wrong version.");
- return false;
- }
- if (_magic != CDS_ARCHIVE_MAGIC && _magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
- FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
- return false;
- }
- char header_version[JVM_IDENT_MAX];
- get_header_version(header_version);
- if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
- log_info(class, path)("expected: %s", header_version);
- log_info(class, path)("actual: %s", _jvm_ident);
- FileMapInfo::fail_continue("The shared archive file was created by a different"
- " version or build of HotSpot");
- return false;
- }
if (_obj_alignment != ObjectAlignmentInBytes) {
FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
" does not equal the current ObjectAlignmentInBytes of " INTX_FORMAT ".",
--- a/src/hotspot/share/memory/heapInspection.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/heapInspection.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -123,7 +123,7 @@
KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
// Can happen if k is an archived class that we haven't loaded yet.
- if (k->java_mirror() == NULL) {
+ if (k->java_mirror_no_keepalive() == NULL) {
return NULL;
}
@@ -719,7 +719,7 @@
ResourceMark rm;
RecordInstanceClosure ric(cit, filter);
- Universe::heap()->object_iterate(&ric);
+ Universe::heap()->safe_object_iterate(&ric);
return ric.missed_count();
}
@@ -792,8 +792,5 @@
// Iterate over objects in the heap
FindInstanceClosure fic(k, result);
- // If this operation encounters a bad object when using CMS,
- // consider using safe_object_iterate() which avoids metadata
- // objects that may contain bad references.
- Universe::heap()->object_iterate(&fic);
+ Universe::heap()->safe_object_iterate(&fic);
}
--- a/src/hotspot/share/memory/iterator.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/iterator.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -144,18 +144,28 @@
void do_cld(ClassLoaderData* cld);
};
-// The base class for all concurrent marking closures,
-// that participates in class unloading.
-// It's used to proxy through the metadata to the oops defined in them.
-class MetadataVisitingOopIterateClosure: public OopIterateClosure {
+class ClaimMetadataVisitingOopIterateClosure : public OopIterateClosure {
+ protected:
+ const int _claim;
+
public:
- MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd = NULL) : OopIterateClosure(rd) { }
+ ClaimMetadataVisitingOopIterateClosure(int claim, ReferenceDiscoverer* rd = NULL) :
+ OopIterateClosure(rd),
+ _claim(claim) { }
virtual bool do_metadata() { return true; }
virtual void do_klass(Klass* k);
virtual void do_cld(ClassLoaderData* cld);
};
+// The base class for all concurrent marking closures,
+// that participates in class unloading.
+// It's used to proxy through the metadata to the oops defined in them.
+class MetadataVisitingOopIterateClosure: public ClaimMetadataVisitingOopIterateClosure {
+ public:
+ MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd = NULL);
+};
+
// ObjectClosure is used for iterating through an object space
class ObjectClosure : public Closure {
--- a/src/hotspot/share/memory/iterator.inline.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/iterator.inline.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -39,13 +39,17 @@
#include "oops/typeArrayKlass.inline.hpp"
#include "utilities/debug.hpp"
-inline void MetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) {
- cld->oops_do(this, ClassLoaderData::_claim_strong);
+// Defaults to strong claiming.
+inline MetadataVisitingOopIterateClosure::MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd) :
+ ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_strong, rd) {}
+
+inline void ClaimMetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) {
+ cld->oops_do(this, _claim);
}
-inline void MetadataVisitingOopIterateClosure::do_klass(Klass* k) {
+inline void ClaimMetadataVisitingOopIterateClosure::do_klass(Klass* k) {
ClassLoaderData* cld = k->class_loader_data();
- MetadataVisitingOopIterateClosure::do_cld(cld);
+ ClaimMetadataVisitingOopIterateClosure::do_cld(cld);
}
#ifdef ASSERT
--- a/src/hotspot/share/memory/metaspace.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/metaspace.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -471,9 +471,36 @@
return cm->chunk_free_list_summary();
}
-void MetaspaceUtils::print_metaspace_change(size_t prev_metadata_used) {
- log_info(gc, metaspace)("Metaspace: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)",
- prev_metadata_used/K, used_bytes()/K, reserved_bytes()/K);
+void MetaspaceUtils::print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values) {
+ const metaspace::MetaspaceSizesSnapshot meta_values;
+
+ if (Metaspace::using_class_space()) {
+ log_info(gc, metaspace)(HEAP_CHANGE_FORMAT" "
+ HEAP_CHANGE_FORMAT" "
+ HEAP_CHANGE_FORMAT,
+ HEAP_CHANGE_FORMAT_ARGS("Metaspace",
+ pre_meta_values.used(),
+ pre_meta_values.committed(),
+ meta_values.used(),
+ meta_values.committed()),
+ HEAP_CHANGE_FORMAT_ARGS("NonClass",
+ pre_meta_values.non_class_used(),
+ pre_meta_values.non_class_committed(),
+ meta_values.non_class_used(),
+ meta_values.non_class_committed()),
+ HEAP_CHANGE_FORMAT_ARGS("Class",
+ pre_meta_values.class_used(),
+ pre_meta_values.class_committed(),
+ meta_values.class_used(),
+ meta_values.class_committed()));
+ } else {
+ log_info(gc, metaspace)(HEAP_CHANGE_FORMAT,
+ HEAP_CHANGE_FORMAT_ARGS("Metaspace",
+ pre_meta_values.used(),
+ pre_meta_values.committed(),
+ meta_values.used(),
+ meta_values.committed()));
+ }
}
void MetaspaceUtils::print_on(outputStream* out) {
@@ -557,6 +584,11 @@
// unlike print_report() is guaranteed not to lock or to walk the CLDG.
void MetaspaceUtils::print_basic_report(outputStream* out, size_t scale) {
+ if (!Metaspace::initialized()) {
+ out->print_cr("Metaspace not yet initialized.");
+ return;
+ }
+
out->cr();
out->print_cr("Usage:");
@@ -645,6 +677,11 @@
void MetaspaceUtils::print_report(outputStream* out, size_t scale, int flags) {
+ if (!Metaspace::initialized()) {
+ out->print_cr("Metaspace not yet initialized.");
+ return;
+ }
+
const bool print_loaders = (flags & rf_show_loaders) > 0;
const bool print_classes = (flags & rf_show_classes) > 0;
const bool print_by_chunktype = (flags & rf_break_down_by_chunktype) > 0;
@@ -932,6 +969,8 @@
ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
ChunkManager* Metaspace::_chunk_manager_class = NULL;
+bool Metaspace::_initialized = false;
+
#define VIRTUALSPACEMULTIPLIER 2
#ifdef _LP64
@@ -1258,6 +1297,9 @@
}
_tracer = new MetaspaceTracer();
+
+ _initialized = true;
+
}
void Metaspace::post_initialize() {
@@ -1588,71 +1630,6 @@
/////////////// Unit tests ///////////////
-#ifndef PRODUCT
-
-class TestMetaspaceUtilsTest : AllStatic {
- public:
- static void test_reserved() {
- size_t reserved = MetaspaceUtils::reserved_bytes();
-
- assert(reserved > 0, "assert");
-
- size_t committed = MetaspaceUtils::committed_bytes();
- assert(committed <= reserved, "assert");
-
- size_t reserved_metadata = MetaspaceUtils::reserved_bytes(Metaspace::NonClassType);
- assert(reserved_metadata > 0, "assert");
- assert(reserved_metadata <= reserved, "assert");
-
- if (UseCompressedClassPointers) {
- size_t reserved_class = MetaspaceUtils::reserved_bytes(Metaspace::ClassType);
- assert(reserved_class > 0, "assert");
- assert(reserved_class < reserved, "assert");
- }
- }
-
- static void test_committed() {
- size_t committed = MetaspaceUtils::committed_bytes();
-
- assert(committed > 0, "assert");
-
- size_t reserved = MetaspaceUtils::reserved_bytes();
- assert(committed <= reserved, "assert");
-
- size_t committed_metadata = MetaspaceUtils::committed_bytes(Metaspace::NonClassType);
- assert(committed_metadata > 0, "assert");
- assert(committed_metadata <= committed, "assert");
-
- if (UseCompressedClassPointers) {
- size_t committed_class = MetaspaceUtils::committed_bytes(Metaspace::ClassType);
- assert(committed_class > 0, "assert");
- assert(committed_class < committed, "assert");
- }
- }
-
- static void test_virtual_space_list_large_chunk() {
- VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity());
- MutexLocker cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
- // A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be
- // vm_allocation_granularity aligned on Windows.
- size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord));
- large_size += (os::vm_page_size()/BytesPerWord);
- vs_list->get_new_chunk(large_size, 0);
- }
-
- static void test() {
- test_reserved();
- test_committed();
- test_virtual_space_list_large_chunk();
- }
-};
-
-void TestMetaspaceUtils_test() {
- TestMetaspaceUtilsTest::test();
-}
-
-#endif // !PRODUCT
-
struct chunkmanager_statistics_t {
int num_specialized_chunks;
int num_small_chunks;
--- a/src/hotspot/share/memory/metaspace.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/memory/metaspace.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -28,6 +28,7 @@
#include "memory/memRegion.hpp"
#include "memory/metaspaceChunkFreeListSummary.hpp"
#include "memory/virtualspace.hpp"
+#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
#include "utilities/exceptions.hpp"
// Metaspace
@@ -139,6 +140,8 @@
static const MetaspaceTracer* _tracer;
+ static bool _initialized;
+
public:
static metaspace::VirtualSpaceList* space_list() { return _space_list; }
static metaspace::VirtualSpaceList* class_space_list() { return _class_space_list; }
@@ -224,6 +227,8 @@
return mdType == ClassType && using_class_space();
}
+ static bool initialized() { return _initialized; }
+
};
// Manages the metaspace portion belonging to a class loader
@@ -410,8 +415,8 @@
static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
- // Print change in used metadata.
- static void print_metaspace_change(size_t prev_metadata_used);
+ // Log change in used metadata.
+ static void print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values);
static void print_on(outputStream * out);
// Prints an ASCII representation of the given space.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/metaspace/metaspaceSizesSnapshot.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Twitter, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "memory/metaspace.hpp"
+#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
+
+namespace metaspace {
+
+MetaspaceSizesSnapshot::MetaspaceSizesSnapshot()
+ : _used(MetaspaceUtils::used_bytes()),
+ _committed(MetaspaceUtils::committed_bytes()),
+ _non_class_used(MetaspaceUtils::used_bytes(Metaspace::NonClassType)),
+ _non_class_committed(MetaspaceUtils::committed_bytes(Metaspace::NonClassType)),
+ _class_used(MetaspaceUtils::used_bytes(Metaspace::ClassType)),
+ _class_committed(MetaspaceUtils::committed_bytes(Metaspace::ClassType)) { }
+
+} // namespace metaspace
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/metaspace/metaspaceSizesSnapshot.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Twitter, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_MEMORY_METASPACE_METASPACESIZESSNAPSHOT_HPP
+#define SHARE_MEMORY_METASPACE_METASPACESIZESSNAPSHOT_HPP
+
+namespace metaspace {
+
+class MetaspaceSizesSnapshot {
+public:
+ MetaspaceSizesSnapshot();
+
+ size_t used() const { return _used; }
+ size_t committed() const { return _committed; }
+ size_t non_class_used() const { return _non_class_used; }
+ size_t non_class_committed() const { return _non_class_committed; }
+ size_t class_used() const { return _class_used; }
+ size_t class_committed() const { return _class_committed; }
+
+private:
+ const size_t _used;
+ const size_t _committed;
+ const size_t _non_class_used;
+ const size_t _non_class_committed;
+ const size_t _class_used;
+ const size_t _class_committed;
+};
+
+} // namespace metaspace
+
+#endif // SHARE_MEMORY_METASPACE_METASPACESIZESSNAPSHOT_HPP
--- a/src/hotspot/share/oops/klass.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/oops/klass.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -767,7 +767,7 @@
// Size Statistics
void Klass::collect_statistics(KlassSizeStats *sz) const {
sz->_klass_bytes = sz->count(this);
- sz->_mirror_bytes = sz->count(java_mirror());
+ sz->_mirror_bytes = sz->count(java_mirror_no_keepalive());
sz->_secondary_supers_bytes = sz->count_array(secondary_supers());
sz->_ro_bytes += sz->_secondary_supers_bytes;
--- a/src/hotspot/share/oops/klassVtable.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/oops/klassVtable.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -638,6 +638,7 @@
Method* super_method = NULL;
InstanceKlass *holder = NULL;
Method* recheck_method = NULL;
+ bool found_pkg_prvt_method = false;
while (k != NULL) {
// lookup through the hierarchy for a method with matching name and sign.
super_method = InstanceKlass::cast(k)->lookup_method(name, signature);
@@ -659,6 +660,16 @@
return false;
// else keep looking for transitive overrides
}
+ // If we get here then one of the super classes has a package private method
+ // that will not get overridden because it is in a different package. But,
+ // that package private method does "override" any matching methods in super
+ // interfaces, so there will be no miranda vtable entry created. So, set flag
+ // to TRUE for use below, in case there are no methods in super classes that
+ // this target method overrides.
+ assert(super_method->is_package_private(), "super_method must be package private");
+ assert(!superk->is_same_class_package(classloader(), classname),
+ "Must be different packages");
+ found_pkg_prvt_method = true;
}
// Start with lookup result and continue to search up, for versions supporting transitive override
@@ -669,6 +680,15 @@
}
}
+ // If found_pkg_prvt_method is set, then the ONLY matching method in the
+ // superclasses is package private in another package. That matching method will
+ // prevent a miranda vtable entry from being created. Because the target method can not
+ // override the package private method in another package, then it needs to be the root
+ // for its own vtable entry.
+ if (found_pkg_prvt_method) {
+ return true;
+ }
+
// if the target method is public or protected it may have a matching
// miranda method in the super, whose entry it should re-use.
// Actually, to handle cases that javac would not generate, we need
@@ -676,7 +696,7 @@
const InstanceKlass *sk = InstanceKlass::cast(super);
if (sk->has_miranda_methods()) {
if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) {
- return false; // found a matching miranda; we do not need a new entry
+ return false; // found a matching miranda; we do not need a new entry
}
}
return true; // found no match; we need a new entry
--- a/src/hotspot/share/oops/method.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/oops/method.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -146,6 +146,12 @@
return adapter()->get_c2i_unverified_entry();
}
+address Method::get_c2i_no_clinit_check_entry() {
+ assert(VM_Version::supports_fast_class_init_checks(), "");
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_c2i_no_clinit_check_entry();
+}
+
char* Method::name_and_sig_as_C_string() const {
return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature());
}
@@ -842,10 +848,7 @@
if (comp_level == CompLevel_all) {
tty->print("all levels ");
} else {
- tty->print("levels ");
- for (int i = (int)CompLevel_none; i <= comp_level; i++) {
- tty->print("%d ", i);
- }
+ tty->print("level %d ", comp_level);
}
this->print_short_name(tty);
int size = this->code_size();
@@ -1048,7 +1051,7 @@
_c2i_entry ---------------------------------+->[c2i entry..]
_i2i_entry -------------+ _i2c_entry ---------------+-> [i2c entry..] |
_from_interpreted_entry | _c2i_unverified_entry | |
- | | | |
+ | | _c2i_no_clinit_check_entry| |
| | (_cds_entry_table: CODE) | |
| +->[0]: jmp _entry_table[0] --> (i2i_entry_for "zero_locals") | |
| | (allocated at run time) | |
@@ -1920,7 +1923,6 @@
Thread *thread = Thread::current();
*method->bcp_from(_bci) = Bytecodes::_breakpoint;
method->incr_number_of_breakpoints(thread);
- SystemDictionary::notice_modification();
{
// Deoptimize all dependents on this method
HandleMark hm(thread);
--- a/src/hotspot/share/oops/method.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/oops/method.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -481,6 +481,7 @@
address get_i2c_entry();
address get_c2i_entry();
address get_c2i_unverified_entry();
+ address get_c2i_no_clinit_check_entry();
AdapterHandlerEntry* adapter() const {
return constMethod()->adapter();
}
--- a/src/hotspot/share/oops/methodData.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/oops/methodData.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1607,11 +1607,14 @@
bool MethodData::profile_unsafe(const methodHandle& m, int bci) {
Bytecode_invoke inv(m , bci);
- if (inv.is_invokevirtual() && inv.klass() == vmSymbols::jdk_internal_misc_Unsafe()) {
- ResourceMark rm;
- char* name = inv.name()->as_C_string();
- if (!strncmp(name, "get", 3) || !strncmp(name, "put", 3)) {
- return true;
+ if (inv.is_invokevirtual()) {
+ if (inv.klass() == vmSymbols::jdk_internal_misc_Unsafe() ||
+ inv.klass() == vmSymbols::sun_misc_Unsafe()) {
+ ResourceMark rm;
+ char* name = inv.name()->as_C_string();
+ if (!strncmp(name, "get", 3) || !strncmp(name, "put", 3)) {
+ return true;
+ }
}
}
return false;
--- a/src/hotspot/share/opto/addnode.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/addnode.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -929,3 +929,91 @@
// Otherwise just MIN them bits.
return TypeInt::make( MIN2(r0->_lo,r1->_lo), MIN2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) );
}
+
+//------------------------------add_ring---------------------------------------
+const Type *MinFNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeF *r0 = t0->is_float_constant();
+ const TypeF *r1 = t1->is_float_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ float f0 = r0->getf();
+ float f1 = r1->getf();
+ if (f0 != 0.0f || f1 != 0.0f) {
+ return f0 < f1 ? r0 : r1;
+ }
+
+ // handle min of 0.0, -0.0 case.
+ return (jint_cast(f0) < jint_cast(f1)) ? r0 : r1;
+}
+
+//------------------------------add_ring---------------------------------------
+const Type *MinDNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeD *r0 = t0->is_double_constant();
+ const TypeD *r1 = t1->is_double_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ double d0 = r0->getd();
+ double d1 = r1->getd();
+ if (d0 != 0.0 || d1 != 0.0) {
+ return d0 < d1 ? r0 : r1;
+ }
+
+ // handle min of 0.0, -0.0 case.
+ return (jlong_cast(d0) < jlong_cast(d1)) ? r0 : r1;
+}
+
+//------------------------------add_ring---------------------------------------
+const Type *MaxFNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeF *r0 = t0->is_float_constant();
+ const TypeF *r1 = t1->is_float_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ float f0 = r0->getf();
+ float f1 = r1->getf();
+ if (f0 != 0.0f || f1 != 0.0f) {
+ return f0 > f1 ? r0 : r1;
+ }
+
+ // handle max of 0.0,-0.0 case.
+ return (jint_cast(f0) > jint_cast(f1)) ? r0 : r1;
+}
+
+//------------------------------add_ring---------------------------------------
+const Type *MaxDNode::add_ring( const Type *t0, const Type *t1 ) const {
+ const TypeD *r0 = t0->is_double_constant();
+ const TypeD *r1 = t1->is_double_constant();
+
+ if (r0->is_nan()) {
+ return r0;
+ }
+ if (r1->is_nan()) {
+ return r1;
+ }
+
+ double d0 = r0->getd();
+ double d1 = r1->getd();
+ if (d0 != 0.0 || d1 != 0.0) {
+ return d0 > d1 ? r0 : r1;
+ }
+
+ // handle max of 0.0, -0.0 case.
+ return (jlong_cast(d0) > jlong_cast(d1)) ? r0 : r1;
+}
--- a/src/hotspot/share/opto/addnode.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/addnode.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -255,7 +255,7 @@
public:
MaxFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::FLOAT; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeF::NEG_INF; }
virtual const Type *bottom_type() const { return Type::FLOAT; }
virtual uint ideal_reg() const { return Op_RegF; }
@@ -267,7 +267,7 @@
public:
MinFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::FLOAT; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeF::POS_INF; }
virtual const Type *bottom_type() const { return Type::FLOAT; }
virtual uint ideal_reg() const { return Op_RegF; }
@@ -279,7 +279,7 @@
public:
MaxDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::DOUBLE; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeD::NEG_INF; }
virtual const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -291,7 +291,7 @@
public:
MinDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
virtual int Opcode() const;
- virtual const Type *add_ring(const Type*, const Type*) const { return Type::DOUBLE; }
+ virtual const Type *add_ring(const Type*, const Type*) const;
virtual const Type *add_id() const { return TypeD::POS_INF; }
virtual const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
--- a/src/hotspot/share/opto/callGenerator.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/callGenerator.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -96,13 +96,6 @@
Parse parser(jvms, method(), _expected_uses);
// Grab signature for matching/allocation
-#ifdef ASSERT
- if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) {
- assert(C->env()->system_dictionary_modification_counter_changed(),
- "Must invalidate if TypeFuncs differ");
- }
-#endif
-
GraphKit& exits = parser.exits();
if (C->failing()) {
--- a/src/hotspot/share/opto/compile.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/compile.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -465,7 +465,6 @@
compile->set_type_dict(NULL);
compile->set_clone_map(new Dict(cmpkey, hashkey, _compile->comp_arena()));
compile->clone_map().set_clone_idx(0);
- compile->set_type_hwm(NULL);
compile->set_type_last_size(0);
compile->set_last_tf(NULL, NULL);
compile->set_indexSet_arena(NULL);
--- a/src/hotspot/share/opto/compile.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/compile.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -478,7 +478,6 @@
Arena* _type_arena; // Alias for _Compile_types except in Initialize_shared()
Dict* _type_dict; // Intern table
CloneMap _clone_map; // used for recording history of cloned nodes
- void* _type_hwm; // Last allocation (see Type::operator new/delete)
size_t _type_last_size; // Last allocation size (see Type::operator new/delete)
ciMethod* _last_tf_m; // Cache for
const TypeFunc* _last_tf; // TypeFunc::make
@@ -977,14 +976,12 @@
// Type management
Arena* type_arena() { return _type_arena; }
Dict* type_dict() { return _type_dict; }
- void* type_hwm() { return _type_hwm; }
size_t type_last_size() { return _type_last_size; }
int num_alias_types() { return _num_alias_types; }
void init_type_arena() { _type_arena = &_Compile_types; }
void set_type_arena(Arena* a) { _type_arena = a; }
void set_type_dict(Dict* d) { _type_dict = d; }
- void set_type_hwm(void* p) { _type_hwm = p; }
void set_type_last_size(size_t sz) { _type_last_size = sz; }
const TypeFunc* last_tf(ciMethod* m) {
--- a/src/hotspot/share/opto/escape.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/escape.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -350,6 +350,12 @@
if (n_ptn != NULL)
return; // No need to redefine PointsTo node during first iteration.
+ int opcode = n->Opcode();
+ bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_to_con_graph(this, igvn, delayed_worklist, n, opcode);
+ if (gc_handled) {
+ return; // Ignore node if already handled by GC.
+ }
+
if (n->is_Call()) {
// Arguments to allocation and locking don't escape.
if (n->is_AbstractLock()) {
@@ -382,11 +388,6 @@
if (n_ptn == phantom_obj || n_ptn == null_obj)
return; // Skip predefined nodes.
- int opcode = n->Opcode();
- bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_to_con_graph(this, igvn, delayed_worklist, n, opcode);
- if (gc_handled) {
- return; // Ignore node if already handled by GC.
- }
switch (opcode) {
case Op_AddP: {
Node* base = get_addp_base(n);
--- a/src/hotspot/share/opto/escape.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/escape.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -333,7 +333,6 @@
bool _verify; // verify graph
- JavaObjectNode* phantom_obj; // Unknown object
JavaObjectNode* null_obj;
Node* _pcmp_neq; // ConI(#CC_GT)
Node* _pcmp_eq; // ConI(#CC_EQ)
@@ -343,6 +342,10 @@
Unique_Node_List ideal_nodes; // Used by CG construction and types splitting.
+public:
+ JavaObjectNode* phantom_obj; // Unknown object
+
+private:
// Address of an element in _nodes. Used when the element is to be modified
PointsToNode* ptnode_adr(int idx) const {
// There should be no new ideal nodes during ConnectionGraph build,
@@ -365,12 +368,6 @@
// Add PointsToNode node corresponding to a call
void add_call_node(CallNode* call);
- // Map ideal node to existing PointsTo node (usually phantom_object).
- void map_ideal_node(Node *n, PointsToNode* ptn) {
- assert(ptn != NULL, "only existing PointsTo node");
- _nodes.at_put(n->_idx, ptn);
- }
-
// Create PointsToNode node and add it to Connection Graph.
void add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist);
@@ -594,6 +591,12 @@
add_edge(ptnode_adr(n->_idx), ptn);
}
+ // Map ideal node to existing PointsTo node (usually phantom_object).
+ void map_ideal_node(Node *n, PointsToNode* ptn) {
+ assert(ptn != NULL, "only existing PointsTo node");
+ _nodes.at_put(n->_idx, ptn);
+ }
+
void add_to_congraph_unsafe_access(Node* n, uint opcode, Unique_Node_List* delayed_worklist);
bool add_final_edges_unsafe_access(Node* n, uint opcode);
--- a/src/hotspot/share/opto/lcm.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/lcm.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -170,7 +170,6 @@
case Op_LoadI:
case Op_LoadL:
case Op_LoadP:
- case Op_LoadBarrierSlowReg:
case Op_LoadN:
case Op_LoadS:
case Op_LoadKlass:
--- a/src/hotspot/share/opto/library_call.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/library_call.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -6706,9 +6706,6 @@
fatal_unexpected_iid(id);
break;
}
- if (a->is_Con() || b->is_Con()) {
- return false;
- }
switch (id) {
case vmIntrinsics::_maxF: n = new MaxFNode(a, b); break;
case vmIntrinsics::_minF: n = new MinFNode(a, b); break;
--- a/src/hotspot/share/opto/loopnode.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/loopnode.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -2494,9 +2494,11 @@
}
}
}
- // Add data (x1.5) and control (x1.0) count to estimate iff both are > 0.
+ // Add data and control count (x2.0) to estimate iff both are > 0. This is
+ // a rather pessimistic estimate for the most part, in particular for some
+ // complex loops, but still not enough to capture all loops.
if (ctrl_edge_out_cnt > 0 && data_edge_out_cnt > 0) {
- estimate += ctrl_edge_out_cnt + data_edge_out_cnt + data_edge_out_cnt / 2;
+ estimate += 2 * (ctrl_edge_out_cnt + data_edge_out_cnt);
}
return estimate;
@@ -4292,7 +4294,6 @@
case Op_LoadL:
case Op_LoadS:
case Op_LoadP:
- case Op_LoadBarrierSlowReg:
case Op_LoadN:
case Op_LoadRange:
case Op_LoadD_unaligned:
--- a/src/hotspot/share/opto/node.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/node.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -675,6 +675,7 @@
DEFINE_CLASS_ID(EncodeNarrowPtr, Type, 6)
DEFINE_CLASS_ID(EncodeP, EncodeNarrowPtr, 0)
DEFINE_CLASS_ID(EncodePKlass, EncodeNarrowPtr, 1)
+ DEFINE_CLASS_ID(LoadBarrierSlowReg, Type, 7)
DEFINE_CLASS_ID(Proj, Node, 3)
DEFINE_CLASS_ID(CatchProj, Proj, 0)
@@ -688,7 +689,6 @@
DEFINE_CLASS_ID(Mem, Node, 4)
DEFINE_CLASS_ID(Load, Mem, 0)
DEFINE_CLASS_ID(LoadVector, Load, 0)
- DEFINE_CLASS_ID(LoadBarrierSlowReg, Load, 1)
DEFINE_CLASS_ID(Store, Mem, 1)
DEFINE_CLASS_ID(StoreVector, Store, 0)
DEFINE_CLASS_ID(LoadStore, Mem, 2)
--- a/src/hotspot/share/opto/parse1.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/parse1.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -523,10 +523,6 @@
#ifdef ASSERT
if (depth() == 1) {
assert(C->is_osr_compilation() == this->is_osr_parse(), "OSR in sync");
- if (C->tf() != tf()) {
- assert(C->env()->system_dictionary_modification_counter_changed(),
- "Must invalidate if TypeFuncs differ");
- }
} else {
assert(!this->is_osr_parse(), "no recursive OSR");
}
@@ -1040,19 +1036,12 @@
const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms);
Node* ret_phi = _gvn.transform( _exits.argument(0) );
if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) {
- // In case of concurrent class loading, the type we set for the
- // ret_phi in build_exits() may have been too optimistic and the
- // ret_phi may be top now.
- // Otherwise, we've encountered an error and have to mark the method as
- // not compilable. Just using an assertion instead would be dangerous
- // as this could lead to an infinite compile loop in non-debug builds.
- {
- if (C->env()->system_dictionary_modification_counter_changed()) {
- C->record_failure(C2Compiler::retry_class_loading_during_parsing());
- } else {
- C->record_method_not_compilable("Can't determine return type.");
- }
- }
+ // If the type we set for the ret_phi in build_exits() is too optimistic and
+ // the ret_phi is top now, there's an extremely small chance that it may be due to class
+ // loading. It could also be due to an error, so mark this method as not compilable because
+ // otherwise this could lead to an infinite compile loop.
+ // In any case, this code path is rarely (and never in my testing) reached.
+ C->record_method_not_compilable("Can't determine return type.");
return;
}
if (ret_type->isa_int()) {
--- a/src/hotspot/share/opto/type.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/type.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -411,18 +411,8 @@
}
#define SMALLINT ((juint)3) // a value too insignificant to consider widening
-
-static double pos_dinf() {
- union { int64_t i; double d; } v;
- v.i = CONST64(0x7ff0000000000000);
- return v.d;
-}
-
-static float pos_finf() {
- union { int32_t i; float f; } v;
- v.i = 0x7f800000;
- return v.f;
-}
+#define POSITIVE_INFINITE_F 0x7f800000 // hex representation for IEEE 754 single precision positive infinite
+#define POSITIVE_INFINITE_D 0x7ff0000000000000 // hex representation for IEEE 754 double precision positive infinite
//--------------------------Initialize_shared----------------------------------
void Type::Initialize_shared(Compile* current) {
@@ -453,13 +443,13 @@
TypeF::ZERO = TypeF::make(0.0); // Float 0 (positive zero)
TypeF::ONE = TypeF::make(1.0); // Float 1
- TypeF::POS_INF = TypeF::make(pos_finf());
- TypeF::NEG_INF = TypeF::make(-pos_finf());
+ TypeF::POS_INF = TypeF::make(jfloat_cast(POSITIVE_INFINITE_F));
+ TypeF::NEG_INF = TypeF::make(-jfloat_cast(POSITIVE_INFINITE_F));
TypeD::ZERO = TypeD::make(0.0); // Double 0 (positive zero)
TypeD::ONE = TypeD::make(1.0); // Double 1
- TypeD::POS_INF = TypeD::make(pos_dinf());
- TypeD::NEG_INF = TypeD::make(-pos_dinf());
+ TypeD::POS_INF = TypeD::make(jdouble_cast(POSITIVE_INFINITE_D));
+ TypeD::NEG_INF = TypeD::make(-jdouble_cast(POSITIVE_INFINITE_D));
TypeInt::MINUS_1 = TypeInt::make(-1); // -1
TypeInt::ZERO = TypeInt::make( 0); // 0
--- a/src/hotspot/share/opto/type.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/type.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -184,9 +184,7 @@
inline void* operator new( size_t x ) throw() {
Compile* compile = Compile::current();
compile->set_type_last_size(x);
- void *temp = compile->type_arena()->Amalloc_D(x);
- compile->set_type_hwm(temp);
- return temp;
+ return compile->type_arena()->Amalloc_D(x);
}
inline void operator delete( void* ptr ) {
Compile* compile = Compile::current();
--- a/src/hotspot/share/opto/vectornode.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/opto/vectornode.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -297,7 +297,6 @@
case Op_LoadI: case Op_LoadL:
case Op_LoadF: case Op_LoadD:
case Op_LoadP: case Op_LoadN:
- case Op_LoadBarrierSlowReg:
*start = 0;
*end = 0; // no vector operands
break;
--- a/src/hotspot/share/prims/cdsoffsets.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/prims/cdsoffsets.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -49,6 +49,7 @@
ADD_NEXT(_all, "FileMapHeader::_magic", offset_of(FileMapHeader, _magic)); \
ADD_NEXT(_all, "FileMapHeader::_crc", offset_of(FileMapHeader, _crc)); \
ADD_NEXT(_all, "FileMapHeader::_version", offset_of(FileMapHeader, _version)); \
+ ADD_NEXT(_all, "FileMapHeader::_jvm_ident", offset_of(FileMapHeader, _jvm_ident)); \
ADD_NEXT(_all, "FileMapHeader::_space[0]", offset_of(FileMapHeader, _space)); \
ADD_NEXT(_all, "CDSFileMapRegion::_crc", offset_of(CDSFileMapRegion, _crc)); \
ADD_NEXT(_all, "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used)); \
--- a/src/hotspot/share/prims/jvmti.xsl Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/prims/jvmti.xsl Mon Jul 22 11:08:27 2019 +0530
@@ -62,37 +62,96 @@
<div class="centered" role="banner">
<xsl:apply-templates select="title"/>
</div>
- <ul role="navigation">
- <li>
- <a href="#SpecificationIntro"><b>Introduction</b></a>
- <ul>
- <xsl:for-each select="intro">
+ <nav>
+ <ul>
+ <li>
+ <a href="#SpecificationIntro"><b>Introduction</b></a>
+ <ul>
+ <xsl:for-each select="intro">
+ <li>
+ <a>
+ <xsl:attribute name="href">#<xsl:value-of select="@id"/>
+ </xsl:attribute>
+ <b><xsl:value-of select="@label"/></b>
+ </a>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </li>
+ <li>
+ <a href="#FunctionSection"><b>Functions</b></a>
+ <ul>
+ <xsl:for-each select="functionsection/intro">
+ <li>
+ <a>
+ <xsl:attribute name="href">#<xsl:value-of select="@id"/>
+ </xsl:attribute>
+ <b><xsl:value-of select="@label"/></b>
+ </a>
+ </li>
+ </xsl:for-each>
+ <li>
+ <a href="#FunctionIndex"><b>Function Index</b></a>
+ <ul>
+ <xsl:for-each select="functionsection/category">
+ <li>
+ <a>
+ <xsl:attribute name="href">#<xsl:value-of select="@id"/>
+ </xsl:attribute>
+ <b><xsl:value-of select="@label"/></b>
+ </a>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </li>
+ <li>
+ <a href="#ErrorSection"><b>Error Codes</b></a>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <a href="#EventSection"><b>Events</b></a>
+ <ul>
+ <li>
+ <a href="#EventIndex"><b>Event Index</b></a>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <a href="#DataSection"><b>Data Types</b></a>
+ <ul>
+ <xsl:for-each select="//basetypes">
<li>
<a>
- <xsl:attribute name="href">#<xsl:value-of select="@id"/>
- </xsl:attribute>
- <b><xsl:value-of select="@label"/></b>
+ <xsl:attribute name="href">#<xsl:value-of select="@id"/></xsl:attribute>
+ <b>
+ <xsl:value-of select="@label"/>
+ </b>
</a>
</li>
- </xsl:for-each>
- </ul>
- </li>
- <li>
- <a href="#FunctionSection"><b>Functions</b></a>
- <ul>
- <xsl:for-each select="functionsection/intro">
+ </xsl:for-each>
+ <li>
+ <a href="#StructureTypeDefinitions"><b>Structure Type Definitions</b></a>
+ </li>
+ <li>
+ <a href="#FunctionTypeDefinitions"><b>Function Type Definitions</b></a>
+ </li>
+ <li>
+ <a href="#EnumerationDefinitions"><b>Enumeration Definitions</b></a>
+ </li>
<li>
- <a>
- <xsl:attribute name="href">#<xsl:value-of select="@id"/>
- </xsl:attribute>
- <b><xsl:value-of select="@label"/></b>
- </a>
+ <a href="#FunctionTable"><b>Function Table</b></a>
</li>
- </xsl:for-each>
+ </ul>
+ </li>
+ <li>
+ <a href="#ConstantIndex"><b>Constant Index</b></a>
+ </li>
+ <xsl:if test="$development = 'Show'">
<li>
- <a href="#FunctionIndex"><b>Function Index</b></a>
+ <a href="#SpecificationIssues"><b>Issues</b></a>
<ul>
- <xsl:for-each select="functionsection/category">
+ <xsl:for-each select="issuessection/intro">
<li>
<a>
<xsl:attribute name="href">#<xsl:value-of select="@id"/>
@@ -103,69 +162,12 @@
</xsl:for-each>
</ul>
</li>
- <li>
- <a href="#ErrorSection"><b>Error Codes</b></a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#EventSection"><b>Events</b></a>
- <ul>
- <li>
- <a href="#EventIndex"><b>Event Index</b></a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#DataSection"><b>Data Types</b></a>
- <ul>
- <xsl:for-each select="//basetypes">
- <li>
- <a>
- <xsl:attribute name="href">#<xsl:value-of select="@id"/></xsl:attribute>
- <b>
- <xsl:value-of select="@label"/>
- </b>
- </a>
- </li>
- </xsl:for-each>
- <li>
- <a href="#StructureTypeDefinitions"><b>Structure Type Definitions</b></a>
- </li>
- <li>
- <a href="#FunctionTypeDefinitions"><b>Function Type Definitions</b></a>
- </li>
- <li>
- <a href="#EnumerationDefinitions"><b>Enumeration Definitions</b></a>
- </li>
- <li>
- <a href="#FunctionTable"><b>Function Table</b></a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#ConstantIndex"><b>Constant Index</b></a>
- </li>
- <xsl:if test="$development = 'Show'">
+ </xsl:if>
<li>
- <a href="#SpecificationIssues"><b>Issues</b></a>
- <ul>
- <xsl:for-each select="issuessection/intro">
- <li>
- <a>
- <xsl:attribute name="href">#<xsl:value-of select="@id"/>
- </xsl:attribute>
- <b><xsl:value-of select="@label"/></b>
- </a>
- </li>
- </xsl:for-each>
- </ul>
+ <a href="#ChangeHistory"><b>Change History</b></a>
</li>
- </xsl:if>
- <li>
- <a href="#ChangeHistory"><b>Change History</b></a>
- </li>
- </ul>
+ </ul>
+ </nav>
<!-- end table of contents, begin body -->
<div role="main">
<div class="sep"/>
@@ -212,11 +214,11 @@
<h1>
<xsl:apply-templates/>
</h1>
- <h3>
+ <h2>
<xsl:value-of select="@subtitle"/>
<xsl:text> </xsl:text>
<xsl:call-template name="showbasicversion"/>
- </h3>
+ </h2>
</xsl:template>
<xsl:template match="functionsection">
@@ -363,7 +365,7 @@
</td>
</tr>
<tr>
- <td >
+ <td>
<xsl:apply-templates select="." mode="phaseinfo"/>
</td>
<td>
@@ -642,12 +644,12 @@
</xsl:template>
<xsl:template match="capabilitiestypedef|typedef|uniontypedef">
- <h4>
+ <h3>
<xsl:attribute name="id">
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:value-of select="@label"/>
- </h4>
+ </h3>
<xsl:apply-templates select="." mode="description"/>
<blockquote>
<xsl:apply-templates select="." mode="code"/>
@@ -1951,12 +1953,12 @@
<xsl:if test="@id!=''">
<xsl:choose>
<xsl:when test="@label!=''">
- <h4>
+ <h3>
<xsl:attribute name="id">
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:value-of select="@label"/>
- </h4>
+ </h3>
</xsl:when>
<xsl:otherwise>
<a>
--- a/src/hotspot/share/prims/jvmtiEventController.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiEventController.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -264,7 +264,7 @@
VM_ChangeSingleStep::VM_ChangeSingleStep(bool on)
- : _on(on != 0)
+ : _on(on)
{
}
@@ -331,18 +331,20 @@
}
-// This change must always be occur when at a safepoint.
-// Being at a safepoint causes the interpreter to use the
-// safepoint dispatch table which we overload to find single
-// step points. Just to be sure that it has been set, we
-// call notice_safepoints when turning on single stepping.
-// When we leave our current safepoint, should_post_single_step
-// will be checked by the interpreter, and the table kept
-// or changed accordingly.
+// When _on == true, we use the safepoint interpreter dispatch table
+// to allow us to find the single step points. Otherwise, we switch
+// back to the regular interpreter dispatch table.
+// Note: We call Interpreter::notice_safepoints() and ignore_safepoints()
+// in a VM_Operation to safely make the dispatch table switch. We
+// no longer rely on the safepoint mechanism to do any of this work
+// for us.
void VM_ChangeSingleStep::doit() {
+ log_debug(interpreter, safepoint)("changing single step to '%s'", _on ? "on" : "off");
JvmtiEventControllerPrivate::set_should_post_single_step(_on);
if (_on) {
Interpreter::notice_safepoints();
+ } else {
+ Interpreter::ignore_safepoints();
}
}
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -232,9 +232,6 @@
ResolvedMethodTable::adjust_method_entries(&trace_name_printed);
}
- // Disable any dependent concurrent compilations
- SystemDictionary::notice_modification();
-
// Set flag indicating that some invariants are no longer true.
// See jvmtiExport.hpp for detailed explanation.
JvmtiExport::set_has_redefined_a_class();
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -63,9 +63,6 @@
#if INCLUDE_ZGC
#include "gc/z/zGlobals.hpp"
#endif
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
// JvmtiTagHashmapEntry
//
@@ -3042,14 +3039,6 @@
return false;
}
-#if INCLUDE_JVMCI
- blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
- JVMCI::oops_do(&blk);
- if (blk.stopped()) {
- return false;
- }
-#endif
-
return true;
}
--- a/src/hotspot/share/prims/whitebox.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/prims/whitebox.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -242,7 +242,6 @@
void TestReservedSpace_test();
void TestReserveMemorySpecial_test();
void TestVirtualSpace_test();
-void TestMetaspaceUtils_test();
#endif
WB_ENTRY(void, WB_RunMemoryUnitTests(JNIEnv* env, jobject o))
@@ -250,7 +249,6 @@
TestReservedSpace_test();
TestReserveMemorySpecial_test();
TestVirtualSpace_test();
- TestMetaspaceUtils_test();
#endif
WB_END
--- a/src/hotspot/share/runtime/biasedLocking.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/biasedLocking.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -119,6 +119,7 @@
return _biased_locking_enabled || BiasedLockingStartupDelay == 0;
}
+
// Returns MonitorInfos for all objects locked on this thread in youngest to oldest order
static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thread) {
GrowableArray<MonitorInfo*>* info = thread->cached_monitor_info();
@@ -153,9 +154,13 @@
return info;
}
+
// After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL,
// AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization).
-static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
+BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
+ assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
+ assert(Thread::current()->is_VM_thread(), "must be VMThread");
+
markOop mark = obj->mark();
if (!mark->has_bias_pattern()) {
if (log_is_enabled(Info, biasedlocking)) {
@@ -168,7 +173,7 @@
obj->klass()->external_name(),
(intptr_t) requesting_thread);
}
- return BiasedLocking::NOT_BIASED;
+ return NOT_BIASED;
}
uint age = mark->age();
@@ -214,7 +219,7 @@
} else {
log_trace(biasedlocking)(" Revoked bias of anonymously-biased object");
}
- return BiasedLocking::BIAS_REVOKED;
+ return BIAS_REVOKED;
}
// Handle case where the thread toward which the object was biased has exited
@@ -239,7 +244,7 @@
log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread ("
PTR_FORMAT ")", p2i(biased_thread));
}
- return BiasedLocking::BIAS_REVOKED;
+ return BIAS_REVOKED;
}
// Log at "info" level if not bulk, else "trace" level
@@ -264,7 +269,7 @@
log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
- // Assume recursive case and fix up highest lock later
+ // Assume recursive case and fix up highest lock below
markOop mark = markOopDesc::encode((BasicLock*) NULL);
highest_lock = mon_info->lock();
highest_lock->set_displaced_header(mark);
@@ -279,7 +284,7 @@
// object at it
highest_lock->set_displaced_header(unbiased_prototype);
// Reset object header to point to displaced mark.
- // Must release storing the lock address for platforms without TSO
+ // Must release store the lock address for platforms without TSO
// ordering (e.g. ppc).
obj->release_set_mark(markOopDesc::encode(highest_lock));
assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
@@ -309,7 +314,7 @@
*biased_locker = biased_thread;
}
- return BiasedLocking::BIAS_REVOKED;
+ return BIAS_REVOKED;
}
@@ -321,7 +326,7 @@
};
-static HeuristicsResult update_heuristics(oop o, bool allow_rebias) {
+static HeuristicsResult update_heuristics(oop o) {
markOop mark = o->mark();
if (!mark->has_bias_pattern()) {
return HR_NOT_BIASED;
@@ -374,11 +379,12 @@
}
-static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
+BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o,
bool bulk_rebias,
bool attempt_rebias_of_object,
JavaThread* requesting_thread) {
assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
+ assert(Thread::current()->is_VM_thread(), "must be VMThread");
log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object "
INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
@@ -390,7 +396,6 @@
jlong cur_time = os::javaTimeMillis();
o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
-
Klass* k_o = o->klass();
Klass* klass = k_o;
@@ -432,7 +437,7 @@
// At this point we're done. All we have to do is potentially
// adjust the header of the given object to revoke its bias.
- revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
+ single_revoke_at_safepoint(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
} else {
if (log_is_enabled(Info, biasedlocking)) {
ResourceMark rm;
@@ -454,20 +459,20 @@
oop owner = mon_info->owner();
markOop mark = owner->mark();
if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
- revoke_bias(owner, false, true, requesting_thread, NULL);
+ single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL);
}
}
}
// Must force the bias of the passed object to be forcibly revoked
// as well to ensure guarantees to callers
- revoke_bias(o, false, true, requesting_thread, NULL);
+ single_revoke_at_safepoint(o, false, true, requesting_thread, NULL);
}
} // ThreadsListHandle is destroyed here.
log_info(biasedlocking)("* Ending bulk revocation");
- BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
+ BiasedLocking::Condition status_code = BIAS_REVOKED;
if (attempt_rebias_of_object &&
o->mark()->has_bias_pattern() &&
@@ -475,7 +480,7 @@
markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(),
klass->prototype_header()->bias_epoch());
o->set_mark(new_mark);
- status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
+ status_code = BIAS_REVOKED_AND_REBIASED;
log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
}
@@ -487,77 +492,125 @@
}
-static void clean_up_cached_monitor_info() {
- // Walk the thread list clearing out the cached monitors
- for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
- thr->set_cached_monitor_info(NULL);
+static void clean_up_cached_monitor_info(JavaThread* thread = NULL) {
+ if (thread != NULL) {
+ thread->set_cached_monitor_info(NULL);
+ } else {
+ // Walk the thread list clearing out the cached monitors
+ for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+ thr->set_cached_monitor_info(NULL);
+ }
}
}
-class VM_RevokeBias : public VM_Operation {
-protected:
+class VM_BulkRevokeBias : public VM_Operation {
+private:
Handle* _obj;
- GrowableArray<Handle>* _objs;
JavaThread* _requesting_thread;
+ bool _bulk_rebias;
+ bool _attempt_rebias_of_object;
BiasedLocking::Condition _status_code;
- traceid _biased_locker_id;
uint64_t _safepoint_id;
public:
- VM_RevokeBias(Handle* obj, JavaThread* requesting_thread)
+ VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread,
+ bool bulk_rebias,
+ bool attempt_rebias_of_object)
: _obj(obj)
- , _objs(NULL)
, _requesting_thread(requesting_thread)
+ , _bulk_rebias(bulk_rebias)
+ , _attempt_rebias_of_object(attempt_rebias_of_object)
, _status_code(BiasedLocking::NOT_BIASED)
- , _biased_locker_id(0)
- , _safepoint_id(0) {}
-
- VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread)
- : _obj(NULL)
- , _objs(objs)
- , _requesting_thread(requesting_thread)
- , _status_code(BiasedLocking::NOT_BIASED)
- , _biased_locker_id(0)
, _safepoint_id(0) {}
- virtual VMOp_Type type() const { return VMOp_RevokeBias; }
+ virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; }
+
+ virtual void doit() {
+ _status_code = BiasedLocking::bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
+ _safepoint_id = SafepointSynchronize::safepoint_id();
+ clean_up_cached_monitor_info();
+ }
+
+ bool is_bulk_rebias() const {
+ return _bulk_rebias;
+ }
+
+ BiasedLocking::Condition status_code() const {
+ return _status_code;
+ }
+
+ uint64_t safepoint_id() const {
+ return _safepoint_id;
+ }
+};
+
+
+class RevokeOneBias : public ThreadClosure {
+protected:
+ Handle _obj;
+ JavaThread* _requesting_thread;
+ JavaThread* _biased_locker;
+ BiasedLocking::Condition _status_code;
+ traceid _biased_locker_id;
+
+public:
+ RevokeOneBias(Handle obj, JavaThread* requesting_thread, JavaThread* biased_locker)
+ : _obj(obj)
+ , _requesting_thread(requesting_thread)
+ , _biased_locker(biased_locker)
+ , _status_code(BiasedLocking::NOT_BIASED)
+ , _biased_locker_id(0) {}
+
+ void do_thread(Thread* target) {
+ assert(target == _biased_locker, "Wrong thread");
- virtual bool doit_prologue() {
- // Verify that there is actual work to do since the callers just
- // give us locked object(s). If we don't find any biased objects
- // there is nothing to do and we avoid a safepoint.
- if (_obj != NULL) {
- markOop mark = (*_obj)()->mark();
- if (mark->has_bias_pattern()) {
- return true;
+ oop o = _obj();
+ markOop mark = o->mark();
+
+ if (!mark->has_bias_pattern()) {
+ return;
+ }
+
+ markOop prototype = o->klass()->prototype_header();
+ if (!prototype->has_bias_pattern()) {
+ // This object has a stale bias from before the handshake
+ // was requested. If we fail this race, the object's bias
+ // has been revoked by another thread so we simply return.
+ markOop biased_value = mark;
+ mark = o->cas_set_mark(markOopDesc::prototype()->set_age(mark->age()), mark);
+ assert(!o->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
+ if (biased_value == mark) {
+ _status_code = BiasedLocking::BIAS_REVOKED;
}
- } else {
- for ( int i = 0 ; i < _objs->length(); i++ ) {
- markOop mark = (_objs->at(i))()->mark();
- if (mark->has_bias_pattern()) {
- return true;
+ return;
+ }
+
+ if (_biased_locker == mark->biased_locker()) {
+ if (mark->bias_epoch() == prototype->bias_epoch()) {
+ // Epoch is still valid. This means biaser could be currently
+ // synchronized on this object. We must walk its stack looking
+ // for monitor records associated with this object and change
+ // them to be stack locks if any are found.
+ ResourceMark rm;
+ BiasedLocking::walk_stack_and_revoke(o, _biased_locker);
+ _biased_locker->set_cached_monitor_info(NULL);
+ assert(!o->mark()->has_bias_pattern(), "invariant");
+ _biased_locker_id = JFR_THREAD_ID(_biased_locker);
+ _status_code = BiasedLocking::BIAS_REVOKED;
+ return;
+ } else {
+ markOop biased_value = mark;
+ mark = o->cas_set_mark(markOopDesc::prototype()->set_age(mark->age()), mark);
+ if (mark == biased_value || !mark->has_bias_pattern()) {
+ assert(!o->mark()->has_bias_pattern(), "should be revoked");
+ _status_code = (biased_value == mark) ? BiasedLocking::BIAS_REVOKED : BiasedLocking::NOT_BIASED;
+ return;
}
}
}
- return false;
- }
- virtual void doit() {
- if (_obj != NULL) {
- log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
- JavaThread* biased_locker = NULL;
- _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker);
- if (biased_locker != NULL) {
- _biased_locker_id = JFR_THREAD_ID(biased_locker);
- }
- _safepoint_id = SafepointSynchronize::safepoint_id();
- clean_up_cached_monitor_info();
- return;
- } else {
- log_info(biasedlocking)("Revoking bias with global safepoint:");
- BiasedLocking::revoke_at_safepoint(_objs);
- }
+ _status_code = BiasedLocking::NOT_REVOKED;
}
BiasedLocking::Condition status_code() const {
@@ -567,40 +620,9 @@
traceid biased_locker() const {
return _biased_locker_id;
}
-
- uint64_t safepoint_id() const {
- return _safepoint_id;
- }
};
-class VM_BulkRevokeBias : public VM_RevokeBias {
-private:
- bool _bulk_rebias;
- bool _attempt_rebias_of_object;
-
-public:
- VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread,
- bool bulk_rebias,
- bool attempt_rebias_of_object)
- : VM_RevokeBias(obj, requesting_thread)
- , _bulk_rebias(bulk_rebias)
- , _attempt_rebias_of_object(attempt_rebias_of_object) {}
-
- virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; }
- virtual bool doit_prologue() { return true; }
-
- virtual void doit() {
- _status_code = bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
- _safepoint_id = SafepointSynchronize::safepoint_id();
- clean_up_cached_monitor_info();
- }
-
- bool is_bulk_rebias() const {
- return _bulk_rebias;
- }
-};
-
static void post_self_revocation_event(EventBiasedLockSelfRevocation* event, Klass* k) {
assert(event != NULL, "invariant");
assert(k != NULL, "invariant");
@@ -609,13 +631,13 @@
event->commit();
}
-static void post_revocation_event(EventBiasedLockRevocation* event, Klass* k, VM_RevokeBias* op) {
+static void post_revocation_event(EventBiasedLockRevocation* event, Klass* k, RevokeOneBias* op) {
assert(event != NULL, "invariant");
assert(k != NULL, "invariant");
assert(op != NULL, "invariant");
assert(event->should_commit(), "invariant");
event->set_lockClass(k);
- event->set_safepointId(op->safepoint_id());
+ event->set_safepointId(0);
event->set_previousOwner(op->biased_locker());
event->commit();
}
@@ -631,141 +653,263 @@
event->commit();
}
-BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
- assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
+
+BiasedLocking::Condition BiasedLocking::single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser) {
+
+ EventBiasedLockRevocation event;
+ if (PrintBiasedLockingStatistics) {
+ Atomic::inc(handshakes_count_addr());
+ }
+ log_info(biasedlocking, handshake)("JavaThread " INTPTR_FORMAT " handshaking JavaThread "
+ INTPTR_FORMAT " to revoke object " INTPTR_FORMAT, p2i(requester),
+ p2i(biaser), p2i(obj()));
- // We can revoke the biases of anonymously-biased objects
- // efficiently enough that we should not cause these revocations to
- // update the heuristics because doing so may cause unwanted bulk
- // revocations (which are expensive) to occur.
- markOop mark = obj->mark();
- if (mark->is_biased_anonymously() && !attempt_rebias) {
- // We are probably trying to revoke the bias of this object due to
- // an identity hash code computation. Try to revoke the bias
- // without a safepoint. This is possible if we can successfully
- // compare-and-exchange an unbiased header into the mark word of
- // the object, meaning that no other thread has raced to acquire
- // the bias of the object.
- markOop biased_value = mark;
- markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
- markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
- if (res_mark == biased_value) {
- return BIAS_REVOKED;
+ RevokeOneBias revoke(obj, requester, biaser);
+ bool executed = Handshake::execute(&revoke, biaser);
+ if (revoke.status_code() == NOT_REVOKED) {
+ return NOT_REVOKED;
+ }
+ if (executed) {
+ log_info(biasedlocking, handshake)("Handshake revocation for object " INTPTR_FORMAT " succeeded. Bias was %srevoked",
+ p2i(obj()), (revoke.status_code() == BIAS_REVOKED ? "" : "already "));
+ if (event.should_commit() && revoke.status_code() == BIAS_REVOKED) {
+ post_revocation_event(&event, obj->klass(), &revoke);
}
- } else if (mark->has_bias_pattern()) {
- Klass* k = obj->klass();
- markOop prototype_header = k->prototype_header();
- if (!prototype_header->has_bias_pattern()) {
- // This object has a stale bias from before the bulk revocation
- // for this data type occurred. It's pointless to update the
- // heuristics at this point so simply update the header with a
- // CAS. If we fail this race, the object's bias has been revoked
- // by another thread so we simply return and let the caller deal
- // with it.
- markOop biased_value = mark;
- markOop res_mark = obj->cas_set_mark(prototype_header, mark);
- assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
- return BIAS_REVOKED;
- } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
- // The epoch of this biasing has expired indicating that the
- // object is effectively unbiased. Depending on whether we need
- // to rebias or revoke the bias of this object we can do it
- // efficiently enough with a CAS that we shouldn't update the
- // heuristics. This is normally done in the assembly code but we
- // can reach this point due to various points in the runtime
- // needing to revoke biases.
- if (attempt_rebias) {
- assert(THREAD->is_Java_thread(), "");
- markOop biased_value = mark;
- markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
- markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
- if (res_mark == biased_value) {
- return BIAS_REVOKED_AND_REBIASED;
+ assert(!obj->mark()->has_bias_pattern(), "invariant");
+ return revoke.status_code();
+ } else {
+ // Thread was not alive.
+ // Grab Threads_lock before manually trying to revoke bias. This avoids race with a newly
+ // created JavaThread (that happens to get the same memory address as biaser) synchronizing
+ // on this object.
+ {
+ MutexLocker ml(Threads_lock);
+ markOop mark = obj->mark();
+ // Check if somebody else was able to revoke it before biased thread exited.
+ if (!mark->has_bias_pattern()) {
+ return NOT_BIASED;
+ }
+ ThreadsListHandle tlh;
+ markOop prototype = obj->klass()->prototype_header();
+ if (!prototype->has_bias_pattern() || (!tlh.includes(biaser) && biaser == mark->biased_locker() &&
+ prototype->bias_epoch() == mark->bias_epoch())) {
+ obj->cas_set_mark(markOopDesc::prototype()->set_age(mark->age()), mark);
+ if (event.should_commit()) {
+ post_revocation_event(&event, obj->klass(), &revoke);
}
- } else {
- markOop biased_value = mark;
- markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
- markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
- if (res_mark == biased_value) {
- return BIAS_REVOKED;
- }
+ assert(!obj->mark()->has_bias_pattern(), "bias should be revoked by now");
+ return BIAS_REVOKED;
}
}
}
- HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
- if (heuristics == HR_NOT_BIASED) {
- return NOT_BIASED;
- } else if (heuristics == HR_SINGLE_REVOKE) {
- Klass *k = obj->klass();
- markOop prototype_header = k->prototype_header();
- if (mark->biased_locker() == THREAD &&
- prototype_header->bias_epoch() == mark->bias_epoch()) {
- // A thread is trying to revoke the bias of an object biased
- // toward it, again likely due to an identity hash code
- // computation. We can again avoid a safepoint in this case
- // since we are only going to walk our own stack. There are no
- // races with revocations occurring in other threads because we
- // reach no safepoints in the revocation path.
- // Also check the epoch because even if threads match, another thread
- // can come in with a CAS to steal the bias of an object that has a
- // stale epoch.
- ResourceMark rm;
- log_info(biasedlocking)("Revoking bias by walking my own stack:");
- EventBiasedLockSelfRevocation event;
- BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
- ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
- assert(cond == BIAS_REVOKED, "why not?");
- if (event.should_commit()) {
- post_self_revocation_event(&event, k);
- }
- return cond;
+ return NOT_REVOKED;
+}
+
+
+// Caller should have instantiated a ResourceMark object before calling this method
+void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
+ assert(!SafepointSynchronize::is_at_safepoint() || !ThreadLocalHandshakes,
+ "if ThreadLocalHandshakes is enabled this should always be executed outside safepoints");
+ assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
+
+ markOop mark = obj->mark();
+ assert(mark->biased_locker() == biased_locker &&
+ obj->klass()->prototype_header()->bias_epoch() == mark->bias_epoch(), "invariant");
+
+ log_trace(biasedlocking)("%s(" INTPTR_FORMAT ") revoking object " INTPTR_FORMAT ", mark "
+ INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
+ ", biaser " INTPTR_FORMAT " %s",
+ Thread::current()->is_VM_thread() ? "VMThread" : "JavaThread",
+ p2i(Thread::current()),
+ p2i(obj),
+ p2i(mark),
+ obj->klass()->external_name(),
+ p2i(obj->klass()->prototype_header()),
+ p2i(biased_locker),
+ Thread::current()->is_VM_thread() ? "" : "(walking own stack)");
+
+ markOop unbiased_prototype = markOopDesc::prototype()->set_age(obj->mark()->age());
+
+ GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_locker);
+ BasicLock* highest_lock = NULL;
+ for (int i = 0; i < cached_monitor_info->length(); i++) {
+ MonitorInfo* mon_info = cached_monitor_info->at(i);
+ if (oopDesc::equals(mon_info->owner(), obj)) {
+ log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
+ p2i(mon_info->owner()),
+ p2i(obj));
+ // Assume recursive case and fix up highest lock below
+ markOop mark = markOopDesc::encode((BasicLock*) NULL);
+ highest_lock = mon_info->lock();
+ highest_lock->set_displaced_header(mark);
} else {
- EventBiasedLockRevocation event;
- VM_RevokeBias revoke(&obj, (JavaThread*) THREAD);
- VMThread::execute(&revoke);
- if (event.should_commit() && revoke.status_code() != NOT_BIASED) {
- post_revocation_event(&event, k, &revoke);
- }
- return revoke.status_code();
+ log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
+ p2i(mon_info->owner()),
+ p2i(obj));
}
}
+ if (highest_lock != NULL) {
+ // Fix up highest lock to contain displaced header and point
+ // object at it
+ highest_lock->set_displaced_header(unbiased_prototype);
+ // Reset object header to point to displaced mark.
+ // Must release store the lock address for platforms without TSO
+ // ordering (e.g. ppc).
+ obj->release_set_mark(markOopDesc::encode(highest_lock));
+ assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
+ log_info(biasedlocking)(" Revoked bias of currently-locked object");
+ } else {
+ log_info(biasedlocking)(" Revoked bias of currently-unlocked object");
+ // Store the unlocked value into the object's header.
+ obj->set_mark(unbiased_prototype);
+ }
- assert((heuristics == HR_BULK_REVOKE) ||
- (heuristics == HR_BULK_REBIAS), "?");
- EventBiasedLockClassRevocation event;
- VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD,
- (heuristics == HR_BULK_REBIAS),
- attempt_rebias);
- VMThread::execute(&bulk_revoke);
- if (event.should_commit()) {
- post_class_revocation_event(&event, obj->klass(), &bulk_revoke);
- }
- return bulk_revoke.status_code();
+ assert(!obj->mark()->has_bias_pattern(), "must not be biased");
}
-void BiasedLocking::revoke(GrowableArray<Handle>* objs) {
+BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
- if (objs->length() == 0) {
- return;
+
+ while (true) {
+ // We can revoke the biases of anonymously-biased objects
+ // efficiently enough that we should not cause these revocations to
+ // update the heuristics because doing so may cause unwanted bulk
+ // revocations (which are expensive) to occur.
+ markOop mark = obj->mark();
+ if (mark->is_biased_anonymously() && !attempt_rebias) {
+ // We are probably trying to revoke the bias of this object due to
+ // an identity hash code computation. Try to revoke the bias
+ // without a safepoint. This is possible if we can successfully
+ // compare-and-exchange an unbiased header into the mark word of
+ // the object, meaning that no other thread has raced to acquire
+ // the bias of the object.
+ markOop biased_value = mark;
+ markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
+ markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
+ if (res_mark == biased_value) {
+ return BIAS_REVOKED;
+ }
+ mark = res_mark; // Refresh mark with the latest value.
+ } else if (mark->has_bias_pattern()) {
+ Klass* k = obj->klass();
+ markOop prototype_header = k->prototype_header();
+ if (!prototype_header->has_bias_pattern()) {
+ // This object has a stale bias from before the bulk revocation
+ // for this data type occurred. It's pointless to update the
+ // heuristics at this point so simply update the header with a
+ // CAS. If we fail this race, the object's bias has been revoked
+ // by another thread so we simply return and let the caller deal
+ // with it.
+ obj->cas_set_mark(prototype_header->set_age(mark->age()), mark);
+ assert(!obj->mark()->has_bias_pattern(), "even if we raced, should still be revoked");
+ return BIAS_REVOKED;
+ } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
+ // The epoch of this biasing has expired indicating that the
+ // object is effectively unbiased. Depending on whether we need
+ // to rebias or revoke the bias of this object we can do it
+ // efficiently enough with a CAS that we shouldn't update the
+ // heuristics. This is normally done in the assembly code but we
+ // can reach this point due to various points in the runtime
+ // needing to revoke biases.
+ markOop res_mark;
+ if (attempt_rebias) {
+ assert(THREAD->is_Java_thread(), "");
+ markOop biased_value = mark;
+ markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
+ res_mark = obj->cas_set_mark(rebiased_prototype, mark);
+ if (res_mark == biased_value) {
+ return BIAS_REVOKED_AND_REBIASED;
+ }
+ } else {
+ markOop biased_value = mark;
+ markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
+ res_mark = obj->cas_set_mark(unbiased_prototype, mark);
+ if (res_mark == biased_value) {
+ return BIAS_REVOKED;
+ }
+ }
+ mark = res_mark; // Refresh mark with the latest value.
+ }
+ }
+
+ HeuristicsResult heuristics = update_heuristics(obj());
+ if (heuristics == HR_NOT_BIASED) {
+ return NOT_BIASED;
+ } else if (heuristics == HR_SINGLE_REVOKE) {
+ JavaThread *blt = mark->biased_locker();
+ assert(blt != NULL, "invariant");
+ if (blt == THREAD) {
+ // A thread is trying to revoke the bias of an object biased
+ // toward it, again likely due to an identity hash code
+ // computation. We can again avoid a safepoint/handshake in this case
+ // since we are only going to walk our own stack. There are no
+ // races with revocations occurring in other threads because we
+ // reach no safepoints in the revocation path.
+ EventBiasedLockSelfRevocation event;
+ ResourceMark rm;
+ walk_stack_and_revoke(obj(), blt);
+ blt->set_cached_monitor_info(NULL);
+ assert(!obj->mark()->has_bias_pattern(), "invariant");
+ if (event.should_commit()) {
+ post_self_revocation_event(&event, obj->klass());
+ }
+ return BIAS_REVOKED;
+ } else {
+ BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt);
+ if (cond != NOT_REVOKED) {
+ return cond;
+ }
+ }
+ } else {
+ assert((heuristics == HR_BULK_REVOKE) ||
+ (heuristics == HR_BULK_REBIAS), "?");
+ EventBiasedLockClassRevocation event;
+ VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD,
+ (heuristics == HR_BULK_REBIAS),
+ attempt_rebias);
+ VMThread::execute(&bulk_revoke);
+ if (event.should_commit()) {
+ post_class_revocation_event(&event, obj->klass(), &bulk_revoke);
+ }
+ return bulk_revoke.status_code();
+ }
}
- VM_RevokeBias revoke(objs, JavaThread::current());
- VMThread::execute(&revoke);
+}
+
+// All objects in objs should be locked by biaser
+void BiasedLocking::revoke(GrowableArray<Handle>* objs, JavaThread *biaser) {
+ bool clean_my_cache = false;
+ for (int i = 0; i < objs->length(); i++) {
+ oop obj = (objs->at(i))();
+ markOop mark = obj->mark();
+ if (mark->has_bias_pattern()) {
+ walk_stack_and_revoke(obj, biaser);
+ clean_my_cache = true;
+ }
+ }
+ if (clean_my_cache) {
+ clean_up_cached_monitor_info(biaser);
+ }
}
void BiasedLocking::revoke_at_safepoint(Handle h_obj) {
assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
oop obj = h_obj();
- HeuristicsResult heuristics = update_heuristics(obj, false);
+ HeuristicsResult heuristics = update_heuristics(obj);
if (heuristics == HR_SINGLE_REVOKE) {
- revoke_bias(obj, false, false, NULL, NULL);
+ JavaThread* biased_locker = NULL;
+ single_revoke_at_safepoint(obj, false, false, NULL, &biased_locker);
+ if (biased_locker) {
+ clean_up_cached_monitor_info(biased_locker);
+ }
} else if ((heuristics == HR_BULK_REBIAS) ||
(heuristics == HR_BULK_REVOKE)) {
bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
+ clean_up_cached_monitor_info();
}
- clean_up_cached_monitor_info();
}
@@ -774,9 +918,9 @@
int len = objs->length();
for (int i = 0; i < len; i++) {
oop obj = (objs->at(i))();
- HeuristicsResult heuristics = update_heuristics(obj, false);
+ HeuristicsResult heuristics = update_heuristics(obj);
if (heuristics == HR_SINGLE_REVOKE) {
- revoke_bias(obj, false, false, NULL, NULL);
+ single_revoke_at_safepoint(obj, false, false, NULL, NULL);
} else if ((heuristics == HR_BULK_REBIAS) ||
(heuristics == HR_BULK_REVOKE)) {
bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
@@ -862,6 +1006,7 @@
int* BiasedLocking::anonymously_biased_lock_entry_count_addr() { return _counters.anonymously_biased_lock_entry_count_addr(); }
int* BiasedLocking::rebiased_lock_entry_count_addr() { return _counters.rebiased_lock_entry_count_addr(); }
int* BiasedLocking::revoked_lock_entry_count_addr() { return _counters.revoked_lock_entry_count_addr(); }
+int* BiasedLocking::handshakes_count_addr() { return _counters.handshakes_count_addr(); }
int* BiasedLocking::fast_path_entry_count_addr() { return _counters.fast_path_entry_count_addr(); }
int* BiasedLocking::slow_path_entry_count_addr() { return _counters.slow_path_entry_count_addr(); }
@@ -885,6 +1030,7 @@
tty->print_cr("# anonymously biased lock entries: %d", _anonymously_biased_lock_entry_count);
tty->print_cr("# rebiased lock entries: %d", _rebiased_lock_entry_count);
tty->print_cr("# revoked lock entries: %d", _revoked_lock_entry_count);
+ tty->print_cr("# handshakes entries: %d", _handshakes_count);
tty->print_cr("# fast path lock entries: %d", _fast_path_entry_count);
tty->print_cr("# slow path lock entries: %d", slow_path_entry_count());
}
--- a/src/hotspot/share/runtime/biasedLocking.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/biasedLocking.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -76,17 +76,17 @@
// Revocation of the lock's bias is fairly straightforward. We want to
// restore the object's header and stack-based BasicObjectLocks and
// BasicLocks to the state they would have been in had the object been
-// locked by HotSpot's usual fast locking scheme. To do this, we bring
-// the system to a safepoint and walk the stack of the thread toward
-// which the lock is biased. We find all of the lock records on the
-// stack corresponding to this object, in particular the first /
-// "highest" record. We fill in the highest lock record with the
-// object's displaced header (which is a well-known value given that
-// we don't maintain an identity hash nor age bits for the object
-// while it's in the biased state) and all other lock records with 0,
-// the value for recursive locks. When the safepoint is released, the
-// formerly-biased thread and all other threads revert back to
-// HotSpot's CAS-based locking.
+// locked by HotSpot's usual fast locking scheme. To do this, we execute
+// a handshake with the JavaThread that biased the lock. Inside the
+// handshake we walk the biaser stack searching for all of the lock
+// records corresponding to this object, in particular the first / "highest"
+// record. We fill in the highest lock record with the object's displaced
+// header (which is a well-known value given that we don't maintain an
+// identity hash nor age bits for the object while it's in the biased
+// state) and all other lock records with 0, the value for recursive locks.
+// Alternatively, we can revoke the bias of an object inside a safepoint
+// if we are already in one and we detect that we need to perform a
+// revocation.
//
// This scheme can not handle transfers of biases of single objects
// from thread to thread efficiently, but it can handle bulk transfers
@@ -115,6 +115,7 @@
int _anonymously_biased_lock_entry_count;
int _rebiased_lock_entry_count;
int _revoked_lock_entry_count;
+ int _handshakes_count;
int _fast_path_entry_count;
int _slow_path_entry_count;
@@ -125,6 +126,7 @@
_anonymously_biased_lock_entry_count(0),
_rebiased_lock_entry_count(0),
_revoked_lock_entry_count(0),
+ _handshakes_count(0),
_fast_path_entry_count(0),
_slow_path_entry_count(0) {}
@@ -135,6 +137,7 @@
int* anonymously_biased_lock_entry_count_addr() { return &_anonymously_biased_lock_entry_count; }
int* rebiased_lock_entry_count_addr() { return &_rebiased_lock_entry_count; }
int* revoked_lock_entry_count_addr() { return &_revoked_lock_entry_count; }
+ int* handshakes_count_addr() { return &_handshakes_count; }
int* fast_path_entry_count_addr() { return &_fast_path_entry_count; }
int* slow_path_entry_count_addr() { return &_slow_path_entry_count; }
@@ -146,6 +149,9 @@
class BiasedLocking : AllStatic {
+friend class VM_BulkRevokeBias;
+friend class RevokeOneBias;
+
private:
static BiasedLockingCounters _counters;
@@ -155,15 +161,24 @@
static int* anonymously_biased_lock_entry_count_addr();
static int* rebiased_lock_entry_count_addr();
static int* revoked_lock_entry_count_addr();
+ static int* handshakes_count_addr();
static int* fast_path_entry_count_addr();
static int* slow_path_entry_count_addr();
enum Condition {
NOT_BIASED = 1,
BIAS_REVOKED = 2,
- BIAS_REVOKED_AND_REBIASED = 3
+ BIAS_REVOKED_AND_REBIASED = 3,
+ NOT_REVOKED = 4
};
+private:
+ static Condition single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requester, JavaThread** biaser);
+ static Condition bulk_revoke_or_rebias_at_safepoint(oop o, bool bulk_rebias, bool attempt_rebias, JavaThread* requester);
+ static Condition single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser);
+ static void walk_stack_and_revoke(oop obj, JavaThread* biased_locker);
+
+public:
// This initialization routine should only be called once and
// schedules a PeriodicTask to turn on biased locking a few seconds
// into the VM run to avoid startup time regressions
@@ -178,7 +193,7 @@
// These do not allow rebiasing; they are used by deoptimization to
// ensure that monitors on the stack can be migrated
- static void revoke(GrowableArray<Handle>* objs);
+ static void revoke(GrowableArray<Handle>* objs, JavaThread *biaser);
static void revoke_at_safepoint(Handle obj);
static void revoke_at_safepoint(GrowableArray<Handle>* objs);
--- a/src/hotspot/share/runtime/deoptimization.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/deoptimization.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -840,6 +840,15 @@
}
return NULL;
}
+ oop lookup_raw(intptr_t raw_value) {
+ // Have to cast to avoid little/big-endian problems.
+ if (sizeof(PrimitiveType) > sizeof(jint)) {
+ jlong value = (jlong)raw_value;
+ return lookup(value);
+ }
+ PrimitiveType value = (PrimitiveType)*((jint*)&raw_value);
+ return lookup(value);
+ }
};
typedef BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer> IntegerBoxCache;
@@ -878,6 +887,11 @@
}
return _singleton;
}
+ oop lookup_raw(intptr_t raw_value) {
+ // Have to cast to avoid little/big-endian problems.
+ jboolean value = (jboolean)*((jint*)&raw_value);
+ return lookup(value);
+ }
oop lookup(jboolean value) {
if (value != 0) {
return JNIHandles::resolve_non_null(_true_cache);
@@ -892,18 +906,14 @@
Klass* k = java_lang_Class::as_Klass(bv->klass()->as_ConstantOopReadValue()->value()());
BasicType box_type = SystemDictionary::box_klass_type(k);
if (box_type != T_OBJECT) {
- StackValue* value = StackValue::create_stack_value(fr, reg_map, bv->field_at(0));
+ StackValue* value = StackValue::create_stack_value(fr, reg_map, bv->field_at(box_type == T_LONG ? 1 : 0));
switch(box_type) {
- case T_INT: return IntegerBoxCache::singleton(THREAD)->lookup(value->get_int());
- case T_LONG: {
- StackValue* low = StackValue::create_stack_value(fr, reg_map, bv->field_at(1));
- jlong res = (jlong)low->get_int();
- return LongBoxCache::singleton(THREAD)->lookup(res);
- }
- case T_CHAR: return CharacterBoxCache::singleton(THREAD)->lookup(value->get_int());
- case T_SHORT: return ShortBoxCache::singleton(THREAD)->lookup(value->get_int());
- case T_BYTE: return ByteBoxCache::singleton(THREAD)->lookup(value->get_int());
- case T_BOOLEAN: return BooleanBoxCache::singleton(THREAD)->lookup(value->get_int());
+ case T_INT: return IntegerBoxCache::singleton(THREAD)->lookup_raw(value->get_int());
+ case T_CHAR: return CharacterBoxCache::singleton(THREAD)->lookup_raw(value->get_int());
+ case T_SHORT: return ShortBoxCache::singleton(THREAD)->lookup_raw(value->get_int());
+ case T_BYTE: return ByteBoxCache::singleton(THREAD)->lookup_raw(value->get_int());
+ case T_BOOLEAN: return BooleanBoxCache::singleton(THREAD)->lookup_raw(value->get_int());
+ case T_LONG: return LongBoxCache::singleton(THREAD)->lookup_raw(value->get_int());
default:;
}
}
@@ -1422,7 +1432,7 @@
if (SafepointSynchronize::is_at_safepoint()) {
BiasedLocking::revoke_at_safepoint(objects_to_revoke);
} else {
- BiasedLocking::revoke(objects_to_revoke);
+ BiasedLocking::revoke(objects_to_revoke, thread);
}
}
--- a/src/hotspot/share/runtime/flags/jvmFlag.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1475,19 +1475,13 @@
void JVMFlag::printFlags(outputStream* out, bool withComments, bool printRanges, bool skipDefaults) {
// Print the flags sorted by name
- // note: this method is called before the thread structure is in place
- // which means resource allocation cannot be used.
+ // Note: This method may be called before the thread structure is in place
+ // which means resource allocation cannot be used. Also, it may be
+ // called as part of error reporting, so handle native OOMs gracefully.
// The last entry is the null entry.
const size_t length = JVMFlag::numFlags - 1;
- // Sort
- JVMFlag** array = NEW_C_HEAP_ARRAY(JVMFlag*, length, mtArguments);
- for (size_t i = 0; i < length; i++) {
- array[i] = &flagTable[i];
- }
- qsort(array, length, sizeof(JVMFlag*), compare_flags);
-
// Print
if (!printRanges) {
out->print_cr("[Global flags]");
@@ -1495,12 +1489,28 @@
out->print_cr("[Global flags ranges]");
}
- for (size_t i = 0; i < length; i++) {
- if (array[i]->is_unlocked() && !(skipDefaults && array[i]->is_default())) {
- array[i]->print_on(out, withComments, printRanges);
+ // Sort
+ JVMFlag** array = NEW_C_HEAP_ARRAY_RETURN_NULL(JVMFlag*, length, mtArguments);
+ if (array != NULL) {
+ for (size_t i = 0; i < length; i++) {
+ array[i] = &flagTable[i];
+ }
+ qsort(array, length, sizeof(JVMFlag*), compare_flags);
+
+ for (size_t i = 0; i < length; i++) {
+ if (array[i]->is_unlocked() && !(skipDefaults && array[i]->is_default())) {
+ array[i]->print_on(out, withComments, printRanges);
+ }
+ }
+ FREE_C_HEAP_ARRAY(JVMFlag*, array);
+ } else {
+ // OOM? Print unsorted.
+ for (size_t i = 0; i < length; i++) {
+ if (flagTable[i].is_unlocked() && !(skipDefaults && flagTable[i].is_default())) {
+ flagTable[i].print_on(out, withComments, printRanges);
+ }
}
}
- FREE_C_HEAP_ARRAY(JVMFlag*, array);
}
void JVMFlag::printError(bool verbose, const char* msg, ...) {
--- a/src/hotspot/share/runtime/globals.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/globals.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -466,9 +466,6 @@
develop(bool, UseMallocOnly, false, \
"Use only malloc/free for allocation (no resource area/arena)") \
\
- develop(bool, PrintMallocStatistics, false, \
- "Print malloc/free statistics") \
- \
develop(bool, ZapResourceArea, trueInDebug, \
"Zap freed resource/arena space with 0xABABABAB") \
\
--- a/src/hotspot/share/runtime/handshake.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/handshake.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -46,11 +46,12 @@
class HandshakeThreadsOperation: public HandshakeOperation {
static Semaphore _done;
ThreadClosure* _thread_cl;
-
+ bool _executed;
public:
- HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {}
+ HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl), _executed(false) {}
void do_handshake(JavaThread* thread);
bool thread_has_completed() { return _done.trywait(); }
+ bool executed() const { return _executed; }
#ifdef ASSERT
void check_state() {
@@ -109,24 +110,23 @@
class VM_HandshakeOneThread: public VM_Handshake {
JavaThread* _target;
- bool _thread_alive;
public:
VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
- VM_Handshake(op), _target(target), _thread_alive(false) {}
+ VM_Handshake(op), _target(target) {}
void doit() {
DEBUG_ONLY(_op->check_state();)
- TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
+ TraceTime timer("Finished executing single-target operation (VM_HandshakeOneThread::doit)", TRACETIME_LOG(Info, handshake));
ThreadsListHandle tlh;
if (tlh.includes(_target)) {
set_handshake(_target);
- _thread_alive = true;
} else {
+ log_trace(handshake)("JavaThread " INTPTR_FORMAT " is not alive", p2i(_target));
return;
}
- log_trace(handshake)("Thread signaled, begin processing by VMThtread");
+ log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
jlong start_time = os::elapsed_counter();
do {
if (handshake_has_timed_out(start_time)) {
@@ -146,7 +146,7 @@
VMOp_Type type() const { return VMOp_HandshakeOneThread; }
- bool thread_alive() const { return _thread_alive; }
+ bool executed() const { return _op->executed(); }
};
class VM_HandshakeAllThreads: public VM_Handshake {
@@ -155,7 +155,7 @@
void doit() {
DEBUG_ONLY(_op->check_state();)
- TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
+ TraceTime timer("Finished executing multi-target operation (VM_HandshakeAllThreads::doit)", TRACETIME_LOG(Info, handshake));
JavaThreadIteratorWithHandle jtiwh;
int number_of_threads_issued = 0;
@@ -211,18 +211,19 @@
ThreadClosure* _thread_cl;
Thread* _target_thread;
bool _all_threads;
- bool _thread_alive;
+ bool _executed;
public:
VM_HandshakeFallbackOperation(ThreadClosure* cl) :
- _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
+ _thread_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
- _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
+ _thread_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
void doit() {
+ log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation");
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
if (_all_threads || t == _target_thread) {
if (t == _target_thread) {
- _thread_alive = true;
+ _executed = true;
}
_thread_cl->do_thread(t);
}
@@ -230,7 +231,7 @@
}
VMOp_Type type() const { return VMOp_HandshakeFallback; }
- bool thread_alive() const { return _thread_alive; }
+ bool executed() const { return _executed; }
};
void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
@@ -242,6 +243,7 @@
// Only actually execute the operation for non terminated threads.
if (!thread->is_terminated()) {
_thread_cl->do_thread(thread);
+ _executed = true;
}
// Use the semaphore to inform the VM thread that we have completed the operation
@@ -264,11 +266,11 @@
HandshakeThreadsOperation cto(thread_cl);
VM_HandshakeOneThread handshake(&cto, target);
VMThread::execute(&handshake);
- return handshake.thread_alive();
+ return handshake.executed();
} else {
VM_HandshakeFallbackOperation op(thread_cl, target);
VMThread::execute(&op);
- return op.thread_alive();
+ return op.executed();
}
}
@@ -369,6 +371,7 @@
// getting caught by the semaphore.
if (vmthread_can_process_handshake(target)) {
guarantee(!_semaphore.trywait(), "we should already own the semaphore");
+ log_trace(handshake)("Processing handshake by VMThtread");
_operation->do_handshake(target);
// Disarm after VM thread have executed the operation.
clear_handshake(target);
--- a/src/hotspot/share/runtime/java.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/java.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -203,9 +203,6 @@
}
}
-AllocStats alloc_stats;
-
-
// General statistics printing (profiling ...)
void print_statistics() {
@@ -329,11 +326,6 @@
}
print_bytecode_count();
- if (PrintMallocStatistics) {
- tty->print("allocation stats: ");
- alloc_stats.print();
- tty->cr();
- }
if (PrintSystemDictionaryAtExit) {
ResourceMark rm;
--- a/src/hotspot/share/runtime/javaCalls.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/javaCalls.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -346,9 +346,6 @@
assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");
assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");
-
- CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
-
#if INCLUDE_JVMCI
// Gets the nmethod (if any) that should be called instead of normal target
nmethod* alternative_target = args->alternative_target();
@@ -395,10 +392,6 @@
BasicType result_type = runtime_type_from(result);
bool oop_result_flag = (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY);
- // NOTE: if we move the computation of the result_val_address inside
- // the call to call_stub, the optimizer produces wrong code.
- intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
-
// Find receiver
Handle receiver = (!method->is_static()) ? args->receiver() : Handle();
@@ -436,6 +429,11 @@
{ JavaCallWrapper link(method, receiver, result, CHECK);
{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner
+ // NOTE: if we move the computation of the result_val_address inside
+ // the call to call_stub, the optimizer produces wrong code.
+ intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
+ intptr_t* parameter_address = args->parameters();
+
StubRoutines::call_stub()(
(address)&link,
// (intptr_t*)&(result->_value), // see NOTE above (compiler problem)
@@ -443,7 +441,7 @@
result_type,
method(),
entry_point,
- args->parameters(),
+ parameter_address,
args->size_of_parameters(),
CHECK
);
--- a/src/hotspot/share/runtime/mutex.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/mutex.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -64,8 +64,8 @@
tty = access + 2,
special = tty + 1,
suspend_resume = special + 1,
- vmweak = suspend_resume + 2,
- leaf = vmweak + 2,
+ oopstorage = suspend_resume + 2,
+ leaf = oopstorage + 2,
safepoint = leaf + 10,
barrier = safepoint + 1,
nonleaf = barrier + 1,
--- a/src/hotspot/share/runtime/mutexLocker.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -53,6 +53,8 @@
Mutex* StringTableWeakAlloc_lock = NULL;
Mutex* StringTableWeakActive_lock = NULL;
Mutex* JNIHandleBlockFreeList_lock = NULL;
+Mutex* VMGlobalAlloc_lock = NULL;
+Mutex* VMGlobalActive_lock = NULL;
Mutex* VMWeakAlloc_lock = NULL;
Mutex* VMWeakActive_lock = NULL;
Mutex* ResolvedMethodTableWeakAlloc_lock = NULL;
@@ -161,8 +163,6 @@
#if INCLUDE_JVMCI
Monitor* JVMCI_lock = NULL;
-Mutex* JVMCIGlobalAlloc_lock = NULL;
-Mutex* JVMCIGlobalActive_lock = NULL;
#endif
@@ -216,14 +216,17 @@
def(CGC_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // coordinate between fore- and background GC
def(STS_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never);
- def(VMWeakAlloc_lock , PaddedMutex , vmweak, true, Monitor::_safepoint_check_never);
- def(VMWeakActive_lock , PaddedMutex , vmweak-1, true, Monitor::_safepoint_check_never);
+ def(VMGlobalAlloc_lock , PaddedMutex , oopstorage, true, Monitor::_safepoint_check_never);
+ def(VMGlobalActive_lock , PaddedMutex , oopstorage-1,true, Monitor::_safepoint_check_never);
+
+ def(VMWeakAlloc_lock , PaddedMutex , oopstorage, true, Monitor::_safepoint_check_never);
+ def(VMWeakActive_lock , PaddedMutex , oopstorage-1,true, Monitor::_safepoint_check_never);
- def(StringTableWeakAlloc_lock , PaddedMutex , vmweak, true, Monitor::_safepoint_check_never);
- def(StringTableWeakActive_lock , PaddedMutex , vmweak-1, true, Monitor::_safepoint_check_never);
+ def(StringTableWeakAlloc_lock , PaddedMutex , oopstorage, true, Monitor::_safepoint_check_never);
+ def(StringTableWeakActive_lock , PaddedMutex , oopstorage-1,true, Monitor::_safepoint_check_never);
- def(ResolvedMethodTableWeakAlloc_lock , PaddedMutex , vmweak, true, Monitor::_safepoint_check_never);
- def(ResolvedMethodTableWeakActive_lock , PaddedMutex , vmweak-1, true, Monitor::_safepoint_check_never);
+ def(ResolvedMethodTableWeakAlloc_lock , PaddedMutex , oopstorage, true, Monitor::_safepoint_check_never);
+ def(ResolvedMethodTableWeakActive_lock , PaddedMutex , oopstorage-1, true, Monitor::_safepoint_check_never);
def(FullGCCount_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent
if (UseG1GC) {
@@ -356,8 +359,6 @@
#if INCLUDE_JVMCI
def(JVMCI_lock , PaddedMonitor, nonleaf+2, true, Monitor::_safepoint_check_always);
- def(JVMCIGlobalAlloc_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
- def(JVMCIGlobalActive_lock , PaddedMutex , nonleaf-1, true, Monitor::_safepoint_check_never);
#endif
def(DumpTimeTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
#endif // INCLUDE_CDS
--- a/src/hotspot/share/runtime/mutexLocker.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/mutexLocker.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -46,6 +46,8 @@
extern Mutex* StringTableWeakAlloc_lock; // StringTable weak storage allocate list lock
extern Mutex* StringTableWeakActive_lock; // STringTable weak storage active list lock
extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list
+extern Mutex* VMGlobalAlloc_lock; // VM Global Handles storage allocate list lock
+extern Mutex* VMGlobalActive_lock; // VM Global Handles storage active list lock
extern Mutex* VMWeakAlloc_lock; // VM Weak Handles storage allocate list lock
extern Mutex* VMWeakActive_lock; // VM Weak Handles storage active list lock
extern Mutex* ResolvedMethodTableWeakAlloc_lock; // ResolvedMethodTable weak storage allocate list
@@ -157,8 +159,6 @@
#if INCLUDE_JVMCI
extern Monitor* JVMCI_lock; // Monitor to control initialization of JVMCI
-extern Mutex* JVMCIGlobalAlloc_lock; // JVMCI global storage allocate list lock
-extern Mutex* JVMCIGlobalActive_lock; // JVMCI global storage active list lock
#endif
// A MutexLocker provides mutual exclusion with respect to a given mutex
--- a/src/hotspot/share/runtime/os.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/os.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -360,11 +360,33 @@
switch (sig) {
case SIGBREAK: {
+#if INCLUDE_SERVICES
// Check if the signal is a trigger to start the Attach Listener - in that
// case don't print stack traces.
- if (!DisableAttachMechanism && AttachListener::is_init_trigger()) {
- continue;
+ if (!DisableAttachMechanism) {
+ // Attempt to transit state to AL_INITIALIZING.
+ AttachListenerState cur_state = AttachListener::transit_state(AL_INITIALIZING, AL_NOT_INITIALIZED);
+ if (cur_state == AL_INITIALIZING) {
+ // Attach Listener has been started to initialize. Ignore this signal.
+ continue;
+ } else if (cur_state == AL_NOT_INITIALIZED) {
+ // Start to initialize.
+ if (AttachListener::is_init_trigger()) {
+ // Attach Listener has been initialized.
+ // Accept subsequent request.
+ continue;
+ } else {
+ // Attach Listener could not be started.
+ // So we need to transit the state to AL_NOT_INITIALIZED.
+ AttachListener::set_state(AL_NOT_INITIALIZED);
+ }
+ } else if (AttachListener::check_socket_file()) {
+ // Attach Listener has been started, but unix domain socket file
+ // does not exist. So restart Attach Listener.
+ continue;
+ }
}
+#endif
// Print stack traces
// Any SIGBREAK operations added here should make sure to flush
// the output stream (e.g. tty->flush()) after output. See 4803766.
--- a/src/hotspot/share/runtime/safepoint.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/safepoint.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -35,6 +35,7 @@
#include "code/scopeDesc.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/gcLocker.hpp"
+#include "gc/shared/oopStorage.hpp"
#include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/workgroup.hpp"
#include "interpreter/interpreter.hpp"
@@ -643,6 +644,12 @@
}
}
+ if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP)) {
+ // Don't bother reporting event or time for this very short operation.
+ // To have any utility we'd also want to report whether needed.
+ OopStorage::trigger_cleanup_if_needed();
+ }
+
_subtasks.all_tasks_completed(_num_workers);
}
};
--- a/src/hotspot/share/runtime/safepoint.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/safepoint.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -77,6 +77,7 @@
SAFEPOINT_CLEANUP_STRING_TABLE_REHASH,
SAFEPOINT_CLEANUP_CLD_PURGE,
SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE,
+ SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP,
// Leave this one last.
SAFEPOINT_CLEANUP_NUM_TASKS
};
--- a/src/hotspot/share/runtime/serviceThread.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/serviceThread.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -83,27 +83,9 @@
}
}
-static bool needs_oopstorage_cleanup(OopStorage* const* storages,
- bool* needs_cleanup,
- size_t size) {
- bool any_needs_cleanup = false;
+static void cleanup_oopstorages(OopStorage* const* storages, size_t size) {
for (size_t i = 0; i < size; ++i) {
- assert(!needs_cleanup[i], "precondition");
- if (storages[i]->needs_delete_empty_blocks()) {
- needs_cleanup[i] = true;
- any_needs_cleanup = true;
- }
- }
- return any_needs_cleanup;
-}
-
-static void cleanup_oopstorages(OopStorage* const* storages,
- const bool* needs_cleanup,
- size_t size) {
- for (size_t i = 0; i < size; ++i) {
- if (needs_cleanup[i]) {
- storages[i]->delete_empty_blocks();
- }
+ storages[i]->delete_empty_blocks();
}
}
@@ -112,6 +94,7 @@
JNIHandles::global_handles(),
JNIHandles::weak_global_handles(),
StringTable::weak_storage(),
+ SystemDictionary::vm_global_oop_storage(),
SystemDictionary::vm_weak_oop_storage()
};
const size_t oopstorage_count = ARRAY_SIZE(oopstorages);
@@ -126,7 +109,6 @@
bool resolved_method_table_work = false;
bool protection_domain_table_work = false;
bool oopstorage_work = false;
- bool oopstorages_cleanup[oopstorage_count] = {}; // Zero (false) initialize.
JvmtiDeferredEvent jvmti_event;
{
// Need state transition ThreadBlockInVM so that this thread
@@ -152,10 +134,7 @@
(symboltable_work = SymbolTable::has_work()) |
(resolved_method_table_work = ResolvedMethodTable::has_work()) |
(protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
- (oopstorage_work = needs_oopstorage_cleanup(oopstorages,
- oopstorages_cleanup,
- oopstorage_count)))
-
+ (oopstorage_work = OopStorage::has_cleanup_work_and_reset()))
== 0) {
// Wait until notified that there is some work to do.
ml.wait();
@@ -199,7 +178,7 @@
}
if (oopstorage_work) {
- cleanup_oopstorages(oopstorages, oopstorages_cleanup, oopstorage_count);
+ cleanup_oopstorages(oopstorages, oopstorage_count);
}
}
}
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1446,7 +1446,19 @@
guarantee(callee != NULL && callee->is_method(), "bad handshake");
thread->set_vm_result_2(callee);
thread->set_callee_target(NULL);
- return callee->get_c2i_entry();
+ if (caller_frame.is_entry_frame() && VM_Version::supports_fast_class_init_checks()) {
+ // Bypass class initialization checks in c2i when caller is in native.
+ // JNI calls to static methods don't have class initialization checks.
+ // Fast class initialization checks are present in c2i adapters and call into
+ // SharedRuntime::handle_wrong_method() on the slow path.
+ //
+ // JVM upcalls may land here as well, but there's a proper check present in
+ // LinkResolver::resolve_static_call (called from JavaCalls::call_static),
+ // so bypassing it in c2i adapter is benign.
+ return callee->get_c2i_no_clinit_check_entry();
+ } else {
+ return callee->get_c2i_entry();
+ }
}
// Must be compiled to compiled path which is safe to stackwalk
@@ -2450,9 +2462,9 @@
: BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
// Create a new entry suitable for insertion in the table
- AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
+ AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry, address c2i_no_clinit_check_entry) {
AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
- entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
if (DumpSharedSpaces) {
((CDSAdapterHandlerEntry*)entry)->init();
}
@@ -2601,8 +2613,9 @@
AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
address i2c_entry,
address c2i_entry,
- address c2i_unverified_entry) {
- return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ address c2i_unverified_entry,
+ address c2i_no_clinit_check_entry) {
+ return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
}
AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
@@ -2778,6 +2791,7 @@
if (base == NULL) base = _c2i_entry;
assert(base <= _c2i_entry || _c2i_entry == NULL, "");
assert(base <= _c2i_unverified_entry || _c2i_unverified_entry == NULL, "");
+ assert(base <= _c2i_no_clinit_check_entry || _c2i_no_clinit_check_entry == NULL, "");
return base;
}
@@ -2791,6 +2805,8 @@
_c2i_entry += delta;
if (_c2i_unverified_entry != NULL)
_c2i_unverified_entry += delta;
+ if (_c2i_no_clinit_check_entry != NULL)
+ _c2i_no_clinit_check_entry += delta;
assert(base_address() == new_base, "");
}
@@ -3129,10 +3145,20 @@
}
void AdapterHandlerEntry::print_adapter_on(outputStream* st) const {
- st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
- p2i(this), fingerprint()->as_string(),
- p2i(get_i2c_entry()), p2i(get_c2i_entry()), p2i(get_c2i_unverified_entry()));
-
+ st->print("AHE@" INTPTR_FORMAT ": %s", p2i(this), fingerprint()->as_string());
+ if (get_i2c_entry() != NULL) {
+ st->print(" i2c: " INTPTR_FORMAT, p2i(get_i2c_entry()));
+ }
+ if (get_c2i_entry() != NULL) {
+ st->print(" c2i: " INTPTR_FORMAT, p2i(get_c2i_entry()));
+ }
+ if (get_c2i_unverified_entry() != NULL) {
+ st->print(" c2iUV: " INTPTR_FORMAT, p2i(get_c2i_unverified_entry()));
+ }
+ if (get_c2i_no_clinit_check_entry() != NULL) {
+ st->print(" c2iNCI: " INTPTR_FORMAT, p2i(get_c2i_no_clinit_check_entry()));
+ }
+ st->cr();
}
#if INCLUDE_CDS
--- a/src/hotspot/share/runtime/sharedRuntime.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/sharedRuntime.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -636,6 +636,7 @@
address _i2c_entry;
address _c2i_entry;
address _c2i_unverified_entry;
+ address _c2i_no_clinit_check_entry;
#ifdef ASSERT
// Captures code and signature used to generate this adapter when
@@ -644,11 +645,12 @@
int _saved_code_length;
#endif
- void init(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
+ void init(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry, address c2i_no_clinit_check_entry) {
_fingerprint = fingerprint;
_i2c_entry = i2c_entry;
_c2i_entry = c2i_entry;
_c2i_unverified_entry = c2i_unverified_entry;
+ _c2i_no_clinit_check_entry = c2i_no_clinit_check_entry;
#ifdef ASSERT
_saved_code = NULL;
_saved_code_length = 0;
@@ -661,9 +663,11 @@
AdapterHandlerEntry();
public:
- address get_i2c_entry() const { return _i2c_entry; }
- address get_c2i_entry() const { return _c2i_entry; }
- address get_c2i_unverified_entry() const { return _c2i_unverified_entry; }
+ address get_i2c_entry() const { return _i2c_entry; }
+ address get_c2i_entry() const { return _c2i_entry; }
+ address get_c2i_unverified_entry() const { return _c2i_unverified_entry; }
+ address get_c2i_no_clinit_check_entry() const { return _c2i_no_clinit_check_entry; }
+
address base_address();
void relocate(address new_base);
@@ -709,7 +713,10 @@
public:
static AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint,
- address i2c_entry, address c2i_entry, address c2i_unverified_entry);
+ address i2c_entry,
+ address c2i_entry,
+ address c2i_unverified_entry,
+ address c2i_no_clinit_check_entry = NULL);
static void create_native_wrapper(const methodHandle& method);
static AdapterHandlerEntry* get_adapter(const methodHandle& method);
--- a/src/hotspot/share/runtime/thread.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/thread.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -2969,11 +2969,6 @@
}
}
- // callee_target is never live across a gc point so NULL it here should
- // it still contain a methdOop.
-
- set_callee_target(NULL);
-
assert(vframe_array_head() == NULL, "deopt in progress at a safepoint!");
// If we have deferred set_locals there might be oops waiting to be
// written
--- a/src/hotspot/share/runtime/unhandledOops.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/unhandledOops.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,15 +55,15 @@
// For debugging unhandled oop detector _in the debugger_
// You don't want to turn it on in compiled code here.
-static bool unhandled_oop_print=0;
+static Thread* unhandled_oop_print = NULL;
void UnhandledOops::register_unhandled_oop(oop* op, address pc) {
if (!_thread->is_in_stack((address)op))
return;
- _level ++;
- if (unhandled_oop_print) {
- for (int i=0; i<_level; i++) tty->print(" ");
+ _level++;
+ if (unhandled_oop_print == _thread) {
+ for (int i=0; i < _level; i++) tty->print(" ");
tty->print_cr("r " INTPTR_FORMAT, p2i(op));
}
UnhandledOopEntry entry(op, pc);
@@ -98,11 +98,11 @@
void UnhandledOops::unregister_unhandled_oop(oop* op) {
if (!_thread->is_in_stack((address)op)) return;
- _level --;
- if (unhandled_oop_print) {
- for (int i=0; i<_level; i++) tty->print(" ");
+ if (unhandled_oop_print == _thread) {
+ for (int i=0; i < _level; i++) tty->print(" ");
tty->print_cr("u " INTPTR_FORMAT, p2i(op));
}
+ _level--;
int i = _oop_list->find_from_end(op, match_oop_entry);
assert(i!=-1, "oop not in unhandled_oop_list");
--- a/src/hotspot/share/runtime/vmOperations.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/vmOperations.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -72,11 +72,11 @@
template(ZMarkStart) \
template(ZMarkEnd) \
template(ZRelocateStart) \
+ template(ZVerify) \
template(HandshakeOneThread) \
template(HandshakeAllThreads) \
template(HandshakeFallback) \
template(EnableBiasedLocking) \
- template(RevokeBias) \
template(BulkRevokeBias) \
template(PopulateDumpSharedSpace) \
template(JNIFunctionTableCopier) \
@@ -128,6 +128,7 @@
template(ScavengeMonitors) \
template(PrintMetadata) \
template(GTestExecuteAtSafepoint) \
+ template(JFROldObject) \
class VM_Operation: public CHeapObj<mtInternal> {
public:
--- a/src/hotspot/share/runtime/vmStructs.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/runtime/vmStructs.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -840,7 +840,6 @@
/* CI */ \
/************/ \
\
- nonstatic_field(ciEnv, _system_dictionary_modification_counter, int) \
nonstatic_field(ciEnv, _compiler_data, void*) \
nonstatic_field(ciEnv, _failure_reason, const char*) \
nonstatic_field(ciEnv, _factory, ciObjectFactory*) \
--- a/src/hotspot/share/services/attachListener.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/services/attachListener.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -45,7 +45,7 @@
#include "utilities/debug.hpp"
#include "utilities/formatBuffer.hpp"
-volatile bool AttachListener::_initialized;
+volatile AttachListenerState AttachListener::_state = AL_NOT_INITIALIZED;
// Implementation of "properties" command.
//
@@ -372,6 +372,7 @@
"Should already be setup");
if (AttachListener::pd_init() != 0) {
+ AttachListener::set_state(AL_NOT_INITIALIZED);
return;
}
AttachListener::set_initialized();
@@ -379,6 +380,7 @@
for (;;) {
AttachOperation* op = AttachListener::dequeue();
if (op == NULL) {
+ AttachListener::set_state(AL_NOT_INITIALIZED);
return; // dequeue failed or shutdown
}
@@ -422,6 +424,8 @@
// operation complete - send result and output to client
op->complete(res, &st);
}
+
+ ShouldNotReachHere();
}
bool AttachListener::has_init_error(TRAPS) {
@@ -445,6 +449,7 @@
const char thread_name[] = "Attach Listener";
Handle string = java_lang_String::create_from_str(thread_name, THREAD);
if (has_init_error(THREAD)) {
+ set_state(AL_NOT_INITIALIZED);
return;
}
@@ -456,6 +461,7 @@
string,
THREAD);
if (has_init_error(THREAD)) {
+ set_state(AL_NOT_INITIALIZED);
return;
}
@@ -469,6 +475,7 @@
thread_oop,
THREAD);
if (has_init_error(THREAD)) {
+ set_state(AL_NOT_INITIALIZED);
return;
}
--- a/src/hotspot/share/services/attachListener.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/services/attachListener.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -26,6 +26,8 @@
#define SHARE_SERVICES_ATTACHLISTENER_HPP
#include "memory/allocation.hpp"
+#include "metaprogramming/isRegisteredEnum.hpp"
+#include "runtime/atomic.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
@@ -49,6 +51,14 @@
AttachOperationFunction func;
};
+enum AttachListenerState {
+ AL_NOT_INITIALIZED,
+ AL_INITIALIZING,
+ AL_INITIALIZED
+};
+
+template<> struct IsRegisteredEnum<AttachListenerState> : public TrueType {};
+
class AttachListener: AllStatic {
public:
static void vm_start() NOT_SERVICES_RETURN;
@@ -58,6 +68,9 @@
// invoke to perform clean-up tasks when all clients detach
static void detachall() NOT_SERVICES_RETURN;
+ // check unix domain socket file on filesystem
+ static bool check_socket_file() NOT_SERVICES_RETURN_(false);
+
// indicates if the Attach Listener needs to be created at startup
static bool init_at_startup() NOT_SERVICES_RETURN_(false);
@@ -67,12 +80,31 @@
#if !INCLUDE_SERVICES
static bool is_attach_supported() { return false; }
#else
+
private:
- static volatile bool _initialized;
+ static volatile AttachListenerState _state;
public:
- static bool is_initialized() { return _initialized; }
- static void set_initialized() { _initialized = true; }
+ static void set_state(AttachListenerState new_state) {
+ Atomic::store(new_state, &_state);
+ }
+
+ static AttachListenerState get_state() {
+ return Atomic::load(&_state);
+ }
+
+ static AttachListenerState transit_state(AttachListenerState new_state,
+ AttachListenerState cmp_state) {
+ return Atomic::cmpxchg(new_state, &_state, cmp_state);
+ }
+
+ static bool is_initialized() {
+ return Atomic::load(&_state) == AL_INITIALIZED;
+ }
+
+ static void set_initialized() {
+ Atomic::store(AL_INITIALIZED, &_state);
+ }
// indicates if this VM supports attach-on-demand
static bool is_attach_supported() { return !DisableAttachMechanism; }
--- a/src/hotspot/share/services/diagnosticCommand.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/services/diagnosticCommand.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -880,7 +880,7 @@
return "High: Switches the VM into Java debug mode.";
}
static const JavaPermission permission() {
- JavaPermission p = { "java.lang.management.ManagementPermission", "monitor", NULL };
+ JavaPermission p = { "java.lang.management.ManagementPermission", "control", NULL };
return p;
}
static int num_arguments() { return 0; }
--- a/src/hotspot/share/services/gcNotifier.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/services/gcNotifier.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -159,7 +159,7 @@
gcInfoklass,
vmSymbols::com_sun_management_GcInfo_constructor_signature(),
&constructor_args,
- CHECK_NH);
+ THREAD);
}
void GCNotifier::sendNotification(TRAPS) {
--- a/src/hotspot/share/services/memTracker.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/services/memTracker.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -175,6 +175,22 @@
return true;
}
+
+static volatile bool g_final_report_did_run = false;
+void MemTracker::final_report(outputStream* output) {
+ // This function is called during both error reporting and normal VM exit.
+ // However, it should only ever run once. E.g. if the VM crashes after
+ // printing the final report during normal VM exit, it should not print
+ // the final report again. In addition, it should be guarded from
+ // recursive calls in case NMT reporting itself crashes.
+ if (Atomic::cmpxchg(true, &g_final_report_did_run, false) == false) {
+ NMT_TrackingLevel level = tracking_level();
+ if (level >= NMT_summary) {
+ report(level == NMT_summary, output);
+ }
+ }
+}
+
void MemTracker::report(bool summary_only, outputStream* output) {
assert(output != NULL, "No output stream");
MemBaseline baseline;
@@ -186,12 +202,9 @@
MemDetailReporter rpt(baseline, output);
rpt.report();
output->print("Metaspace:");
- // Metadata reporting requires a safepoint, so avoid it if VM is not in good state.
- assert(!VMError::fatal_error_in_progress(), "Do not report metadata in error report");
- VM_PrintMetadata vmop(output, K,
- MetaspaceUtils::rf_show_loaders |
- MetaspaceUtils::rf_break_down_by_spacetype);
- VMThread::execute(&vmop);
+ // The basic metaspace report avoids any locking and should be safe to
+ // be called at any time.
+ MetaspaceUtils::print_basic_report(output, K);
}
}
}
--- a/src/hotspot/share/services/memTracker.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/services/memTracker.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -271,13 +271,7 @@
}
}
- static void final_report(outputStream* output) {
- NMT_TrackingLevel level = tracking_level();
- if (level >= NMT_summary) {
- report(level == NMT_summary, output);
- }
- }
-
+ static void final_report(outputStream* output);
// Stored baseline
static inline MemBaseline& get_baseline() {
--- a/src/hotspot/share/utilities/debug.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/utilities/debug.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -734,6 +734,10 @@
}
}
+void disarm_assert_poison() {
+ g_assert_poison = &g_dummy;
+}
+
static void store_context(const void* context) {
memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t));
#if defined(__linux) && defined(PPC64)
@@ -746,7 +750,14 @@
bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
if (faulting_address == g_assert_poison) {
// Disarm poison page.
- os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX);
+ if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) {
+#ifdef ASSERT
+ fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)",
+ errno, os::strerror(errno));
+ fflush(stderr);
+#endif
+ return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds.
+ }
// Store Context away.
if (ucVoid) {
const intx my_tid = os::current_thread_id();
--- a/src/hotspot/share/utilities/debug.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/utilities/debug.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -37,6 +37,7 @@
extern char* g_assert_poison;
#define TOUCH_ASSERT_POISON (*g_assert_poison) = 'X';
void initialize_assert_poison();
+void disarm_assert_poison();
bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address);
#else
#define TOUCH_ASSERT_POISON
--- a/src/hotspot/share/utilities/globalDefinitions.hpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp Mon Jul 22 11:08:27 2019 +0530
@@ -308,6 +308,13 @@
return s;
}
+// Memory size transition formatting.
+
+#define HEAP_CHANGE_FORMAT "%s: " SIZE_FORMAT "K(" SIZE_FORMAT "K)->" SIZE_FORMAT "K(" SIZE_FORMAT "K)"
+
+#define HEAP_CHANGE_FORMAT_ARGS(_name_, _prev_used_, _prev_capacity_, _used_, _capacity_) \
+ (_name_), (_prev_used_) / K, (_prev_capacity_) / K, (_used_) / K, (_capacity_) / K
+
//----------------------------------------------------------------------------------------------------
// VM type definitions
--- a/src/hotspot/share/utilities/vmError.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/hotspot/share/utilities/vmError.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -1327,6 +1327,12 @@
// File descriptor to the error log file.
static int fd_log = -1;
+#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
+ // Disarm assertion poison page, since from this point on we do not need this mechanism anymore and it may
+ // cause problems in error handling during native OOM, see JDK-8227275.
+ disarm_assert_poison();
+#endif
+
// Use local fdStream objects only. Do not use global instances whose initialization
// relies on dynamic initialization (see JDK-8214975). Do not rely on these instances
// to carry over into recursions or invocations from other threads.
@@ -1523,6 +1529,11 @@
log.set_fd(-1);
}
+ if (PrintNMTStatistics) {
+ fdStream fds(fd_out);
+ MemTracker::final_report(&fds);
+ }
+
static bool skip_replay = ReplayCompiles; // Do not overwrite file during replay
if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) {
skip_replay = true;
--- a/src/java.base/aix/classes/sun/nio/fs/AixNativeDispatcher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/aix/classes/sun/nio/fs/AixNativeDispatcher.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,9 +26,6 @@
package sun.nio.fs;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
/**
* AIX specific system calls.
*/
@@ -46,11 +43,7 @@
private static native void init();
static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
init();
}
}
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,9 +25,6 @@
package sun.nio.fs;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
/**
* Linux specific system calls.
*/
@@ -121,11 +118,7 @@
private static native void init();
static {
- AccessController.doPrivileged(new PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
init();
}
}
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.*;
import java.io.IOException;
import jdk.internal.misc.Unsafe;
@@ -459,10 +457,6 @@
private static native int poll(int fd1, int fd2) throws UnixException;
static {
- AccessController.doPrivileged(new PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
}
}
--- a/src/java.base/macosx/classes/apple/security/KeychainStore.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/macosx/classes/apple/security/KeychainStore.java Mon Jul 22 11:08:27 2019 +0530
@@ -105,13 +105,7 @@
private static final Debug debug = Debug.getInstance("keystore");
static {
- AccessController.doPrivileged(
- new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("osxsecurity");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("osxsecurity");
try {
PKCS8ShroudedKeyBag_OID = new ObjectIdentifier(keyBag);
pbeWithSHAAnd3KeyTripleDESCBC_OID = new ObjectIdentifier(pbeWithSHAAnd3KeyTripleDESCBC);
--- a/src/java.base/macosx/classes/sun/nio/fs/UTIFileTypeDetector.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/macosx/classes/sun/nio/fs/UTIFileTypeDetector.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,8 +27,6 @@
import java.io.IOException;
import java.nio.file.Path;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
/**
* File type detector that uses a file extension to look up its MIME type
@@ -55,12 +53,6 @@
}
static {
- AccessController.doPrivileged(new PrivilegedAction<>() {
- @Override
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
}
}
--- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1363,8 +1363,11 @@
// Calculate and compare the tag. Only do the decryption
// if and only if the tag matches.
authFinalizeData(ctPlusTag, 0, ctLen, tag, 0);
- if (Arrays.compare(ctPlusTag, ctLen, ctPlusTagLen,
- tag, 0, tag.length) != 0) {
+ long tagCompare = ((long)asLongView.get(ctPlusTag, ctLen) ^
+ (long)asLongView.get(tag, 0)) |
+ ((long)asLongView.get(ctPlusTag, ctLen + Long.BYTES) ^
+ (long)asLongView.get(tag, Long.BYTES));
+ if (tagCompare != 0) {
throw new AEADBadTagException("Tag mismatch");
}
chaCha20Transform(ctPlusTag, 0, ctLen, out, outOff);
--- a/src/java.base/share/classes/java/io/PrintStream.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/io/PrintStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,10 +45,10 @@
* ({@code '\n'}) is written.
*
* <p> All characters printed by a {@code PrintStream} are converted into
- * bytes using the given encoding or charset, or platform's default character
- * encoding if not specified.
+ * bytes using the given encoding or charset, or the platform's default
+ * character encoding if not specified.
* The {@link PrintWriter} class should be used in situations that require
- * writing characters rather than bytes.
+ * writing characters rather than bytes.
*
* <p> This class always replaces malformed and unmappable character sequences with
* the charset's default replacement string.
@@ -121,7 +121,9 @@
}
/**
- * Creates a new print stream. This stream will not flush automatically.
+ * Creates a new print stream, without automatic line flushing, with the
+ * specified OutputStream. Characters written to the stream are converted
+ * to bytes using the platform's default character encoding.
*
* @param out The output stream to which values and objects will be
* printed
@@ -133,11 +135,13 @@
}
/**
- * Creates a new print stream.
+ * Creates a new print stream, with the specified OutputStream and line
+ * flushing. Characters written to the stream are converted to bytes using
+ * the platform's default character encoding.
*
* @param out The output stream to which values and objects will be
* printed
- * @param autoFlush A boolean; if true, the output buffer will be flushed
+ * @param autoFlush Whether the output buffer will be flushed
* whenever a byte array is written, one of the
* {@code println} methods is invoked, or a newline
* character or byte ({@code '\n'}) is written
@@ -149,11 +153,12 @@
}
/**
- * Creates a new print stream.
+ * Creates a new print stream, with the specified OutputStream, line
+ * flushing, and character encoding.
*
* @param out The output stream to which values and objects will be
* printed
- * @param autoFlush A boolean; if true, the output buffer will be flushed
+ * @param autoFlush Whether the output buffer will be flushed
* whenever a byte array is written, one of the
* {@code println} methods is invoked, or a newline
* character or byte ({@code '\n'}) is written
@@ -173,14 +178,14 @@
}
/**
- * Creates a new print stream, with the specified OutputStream, automatic line
+ * Creates a new print stream, with the specified OutputStream, line
* flushing and charset. This convenience constructor creates the necessary
* intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
* which will encode characters using the provided charset.
*
* @param out The output stream to which values and objects will be
* printed
- * @param autoFlush A boolean; if true, the output buffer will be flushed
+ * @param autoFlush Whether the output buffer will be flushed
* whenever a byte array is written, one of the
* {@code println} methods is invoked, or a newline
* character or byte ({@code '\n'}) is written
@@ -700,9 +705,9 @@
/**
* Prints a character. The character is translated into one or more bytes
- * according to the platform's default character encoding, and these bytes
- * are written in exactly the manner of the
- * {@link #write(int)} method.
+ * according to the character encoding given to the constructor, or the
+ * platform's default character encoding if none specified. These bytes
+ * are written in exactly the manner of the {@link #write(int)} method.
*
* @param c The {@code char} to be printed
*/
@@ -768,9 +773,9 @@
/**
* Prints an array of characters. The characters are converted into bytes
- * according to the platform's default character encoding, and these bytes
- * are written in exactly the manner of the
- * {@link #write(int)} method.
+ * according to the character encoding given to the constructor, or the
+ * platform's default character encoding if none specified. These bytes
+ * are written in exactly the manner of the {@link #write(int)} method.
*
* @param s The array of chars to be printed
*
@@ -783,8 +788,9 @@
/**
* Prints a string. If the argument is {@code null} then the string
* {@code "null"} is printed. Otherwise, the string's characters are
- * converted into bytes according to the platform's default character
- * encoding, and these bytes are written in exactly the manner of the
+ * converted into bytes according to the character encoding given to the
+ * constructor, or the platform's default character encoding if none
+ * specified. These bytes are written in exactly the manner of the
* {@link #write(int)} method.
*
* @param s The {@code String} to be printed
--- a/src/java.base/share/classes/java/io/PushbackInputStream.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/io/PushbackInputStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -217,6 +217,7 @@
* @param b the byte array to push back.
* @param off the start offset of the data.
* @param len the number of bytes to push back.
+ * @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IOException If there is not enough room in the pushback
* buffer for the specified number of bytes,
* or this input stream has been closed by
@@ -239,6 +240,7 @@
* value <code>b[1]</code>, and so forth.
*
* @param b the byte array to push back
+ * @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IOException If there is not enough room in the pushback
* buffer for the specified number of bytes,
* or this input stream has been closed by
--- a/src/java.base/share/classes/java/lang/Class.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java Mon Jul 22 11:08:27 2019 +0530
@@ -3491,9 +3491,17 @@
* Returns true if and only if this class was declared as an enum in the
* source code.
*
+ * Note that if an enum constant is declared with a class body,
+ * the class of that enum constant object is an anonymous class
+ * and <em>not</em> the class of the declaring enum type. The
+ * {@link Enum#getDeclaringClass} method of an enum constant can
+ * be used to get the class of the enum type declaring the
+ * constant.
+ *
* @return true if and only if this class was declared as an enum in the
* source code
* @since 1.5
+ * @jls 8.9.1 Enum Constants
*/
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
--- a/src/java.base/share/classes/java/lang/System.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/lang/System.java Mon Jul 22 11:08:27 2019 +0530
@@ -2274,6 +2274,11 @@
public void setCause(Throwable t, Throwable cause) {
t.setCause(cause);
}
+
+ public void loadLibrary(Class<?> caller, String library) {
+ assert library.indexOf(java.io.File.separatorChar) < 0;
+ ClassLoader.loadLibrary(caller, library, false);
+ }
});
}
}
--- a/src/java.base/share/classes/java/lang/Throwable.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/lang/Throwable.java Mon Jul 22 11:08:27 2019 +0530
@@ -25,8 +25,8 @@
package java.lang;
-import java.io.*;
-import java.util.*;
+import java.io.*;
+import java.util.*;
/**
* The {@code Throwable} class is the superclass of all errors and
@@ -904,24 +904,36 @@
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields
- if (suppressedExceptions != null) {
- List<Throwable> suppressed = null;
- if (suppressedExceptions.isEmpty()) {
- // Use the sentinel for a zero-length list
- suppressed = SUPPRESSED_SENTINEL;
- } else { // Copy Throwables to new list
- suppressed = new ArrayList<>(1);
- for (Throwable t : suppressedExceptions) {
+
+ // Set suppressed exceptions and stack trace elements fields
+ // to marker values until the contents from the serial stream
+ // are validated.
+ List<Throwable> candidateSuppressedExceptions = suppressedExceptions;
+ suppressedExceptions = SUPPRESSED_SENTINEL;
+
+ StackTraceElement[] candidateStackTrace = stackTrace;
+ stackTrace = UNASSIGNED_STACK.clone();
+
+ if (candidateSuppressedExceptions != null) {
+ int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions);
+ if (suppressedSize > 0) { // Copy valid Throwables to new list
+ var suppList = new ArrayList<Throwable>(Math.min(100, suppressedSize));
+
+ for (Throwable t : candidateSuppressedExceptions) {
// Enforce constraints on suppressed exceptions in
// case of corrupt or malicious stream.
Objects.requireNonNull(t, NULL_CAUSE_MESSAGE);
if (t == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
- suppressed.add(t);
+ suppList.add(t);
}
+ // If there are any invalid suppressed exceptions,
+ // implicitly use the sentinel value assigned earlier.
+ suppressedExceptions = suppList;
}
- suppressedExceptions = suppressed;
- } // else a null suppressedExceptions field remains null
+ } else {
+ suppressedExceptions = null;
+ }
/*
* For zero-length stack traces, use a clone of
@@ -932,24 +944,41 @@
* the stackTrace needs to be constructed from the information
* in backtrace.
*/
- if (stackTrace != null) {
- if (stackTrace.length == 0) {
- stackTrace = UNASSIGNED_STACK.clone();
- } else if (stackTrace.length == 1 &&
+ if (candidateStackTrace != null) {
+ // Work from a clone of the candidateStackTrace to ensure
+ // consistency of checks.
+ candidateStackTrace = candidateStackTrace.clone();
+ if (candidateStackTrace.length >= 1) {
+ if (candidateStackTrace.length == 1 &&
// Check for the marker of an immutable stack trace
- SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
- stackTrace = null;
- } else { // Verify stack trace elements are non-null.
- for(StackTraceElement ste : stackTrace) {
- Objects.requireNonNull(ste, "null StackTraceElement in serial stream.");
+ SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) {
+ stackTrace = null;
+ } else { // Verify stack trace elements are non-null.
+ for (StackTraceElement ste : candidateStackTrace) {
+ Objects.requireNonNull(ste, "null StackTraceElement in serial stream.");
+ }
+ stackTrace = candidateStackTrace;
}
}
+ }
+ // A null stackTrace field in the serial form can result from
+ // an exception serialized without that field in older JDK
+ // releases; treat such exceptions as having empty stack
+ // traces by leaving stackTrace assigned to a clone of
+ // UNASSIGNED_STACK.
+ }
+
+ private int validateSuppressedExceptionsList(List<Throwable> deserSuppressedExceptions)
+ throws IOException {
+ if (!Object.class.getModule().
+ equals(deserSuppressedExceptions.getClass().getModule())) {
+ throw new StreamCorruptedException("List implementation not in base module.");
} else {
- // A null stackTrace field in the serial form can result
- // from an exception serialized without that field in
- // older JDK releases; treat such exceptions as having
- // empty stack traces.
- stackTrace = UNASSIGNED_STACK.clone();
+ int size = deserSuppressedExceptions.size();
+ if (size < 0) {
+ throw new StreamCorruptedException("Negative list size reported.");
+ }
+ return size;
}
}
--- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -67,13 +67,7 @@
* Load net library into runtime.
*/
static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
}
private static volatile boolean checkedReusePort;
--- a/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -94,13 +94,7 @@
* Load net library into runtime.
*/
static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
}
private static volatile boolean checkedReusePort;
--- a/src/java.base/share/classes/java/net/DatagramPacket.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/DatagramPacket.java Mon Jul 22 11:08:27 2019 +0530
@@ -46,13 +46,7 @@
* Perform class initialization
*/
static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
init();
}
--- a/src/java.base/share/classes/java/net/Inet6AddressImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/Inet6AddressImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package java.net;
import java.io.IOException;
+
+import static java.net.InetAddress.IPv6;
import static java.net.InetAddress.PREFER_IPV6_VALUE;
import static java.net.InetAddress.PREFER_SYSTEM_VALUE;
@@ -70,7 +72,7 @@
* stack system).
*/
java.util.Enumeration<InetAddress> it = netif.getInetAddresses();
- InetAddress inetaddr = null;
+ InetAddress inetaddr;
while (it.hasMoreElements()) {
inetaddr = it.nextElement();
if (inetaddr.getClass().isInstance(addr)) {
@@ -110,20 +112,23 @@
boolean preferIPv6Address =
InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE;
- InetAddress loopback4 = (new Inet4AddressImpl()).loopbackAddress();
- InetAddress loopback6 = new Inet6Address("localhost",
- new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01});
- // Order the candidate addresses by preference.
- InetAddress[] addresses = preferIPv6Address
- ? new InetAddress[] {loopback6, loopback4}
- : new InetAddress[] {loopback4, loopback6};
- // In case of failure, default to the preferred address.
- loopbackAddress = addresses[0];
- // Pick the first candidate address that actually exists.
- for (InetAddress address : addresses) {
+
+ for (int i = 0; i < 2; i++) {
+ InetAddress address;
+ // Order the candidate addresses by preference.
+ if (i == (preferIPv6Address ? 0 : 1)) {
+ address = new Inet6Address("localhost",
+ new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01});
+ } else {
+ address = new Inet4Address("localhost", new byte[]{ 0x7f,0x00,0x00,0x01 });
+ }
+ if (i == 0) {
+ // In case of failure, default to the preferred address.
+ loopbackAddress = address;
+ }
try {
- if (NetworkInterface.getByInetAddress(address) == null) {
+ if (!NetworkInterface.isBoundInetAddress(address)) {
continue;
}
} catch (SocketException e) {
--- a/src/java.base/share/classes/java/net/InetAddress.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/InetAddress.java Mon Jul 22 11:08:27 2019 +0530
@@ -290,7 +290,7 @@
}
/* Used to store the name service provider */
- private static transient NameService nameService = null;
+ private static transient NameService nameService;
/**
* Used to store the best available hostname.
@@ -305,8 +305,7 @@
* Load net library into runtime, and perform initializations.
*/
static {
- String str = java.security.AccessController.doPrivileged(
- new GetPropertyAction("java.net.preferIPv6Addresses"));
+ String str = GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");
if (str == null) {
preferIPv6Address = PREFER_IPV4_VALUE;
} else if (str.equalsIgnoreCase("true")) {
@@ -318,13 +317,7 @@
} else {
preferIPv6Address = PREFER_IPV4_VALUE;
}
- AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
SharedSecrets.setJavaNetInetAddressAccess(
new JavaNetInetAddressAccess() {
public String getOriginalHostName(InetAddress ia) {
--- a/src/java.base/share/classes/java/net/NetworkInterface.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/NetworkInterface.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
import java.util.Arrays;
import java.util.Enumeration;
import java.util.NoSuchElementException;
-import java.security.AccessController;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
@@ -57,13 +56,7 @@
private static final int defaultIndex; /* index of defaultInterface */
static {
- AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
init();
defaultInterface = DefaultInterface.getDefault();
@@ -321,17 +314,16 @@
if (addr == null) {
throw new NullPointerException();
}
- if (addr instanceof Inet4Address) {
- Inet4Address inet4Address = (Inet4Address) addr;
- if (inet4Address.holder.family != InetAddress.IPv4) {
+
+ if (addr.holder.family == InetAddress.IPv4) {
+ if (!(addr instanceof Inet4Address)) {
throw new IllegalArgumentException("invalid family type: "
- + inet4Address.holder.family);
+ + addr.holder.family);
}
- } else if (addr instanceof Inet6Address) {
- Inet6Address inet6Address = (Inet6Address) addr;
- if (inet6Address.holder.family != InetAddress.IPv6) {
+ } else if (addr.holder.family == InetAddress.IPv6) {
+ if (!(addr instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid family type: "
- + inet6Address.holder.family);
+ + addr.holder.family);
}
} else {
throw new IllegalArgumentException("invalid address type: " + addr);
@@ -394,6 +386,23 @@
}
}
+ /**
+ * Checks if the given address is bound to any of the interfaces on this
+ * machine.
+ *
+ * @param addr
+ * The {@code InetAddress} to search with.
+ * @return true iff the addr parameter is currently bound to one of
+ * the interfaces on this machine.
+ *
+ * @throws SocketException
+ * If an I/O error occurs.
+ */
+ /* package-private */ static boolean isBoundInetAddress(InetAddress addr)
+ throws SocketException {
+ return boundInetAddress0(addr);
+ }
+
private static <T> Enumeration<T> enumerationFromArray(T[] a) {
return new Enumeration<>() {
int i = 0;
@@ -431,6 +440,9 @@
private static native NetworkInterface getByIndex0(int index)
throws SocketException;
+ private static native boolean boundInetAddress0(InetAddress addr)
+ throws SocketException;
+
private static native NetworkInterface getByInetAddress0(InetAddress addr)
throws SocketException;
--- a/src/java.base/share/classes/java/net/ServerSocket.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/ServerSocket.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,17 +27,11 @@
import java.io.FileDescriptor;
import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.nio.channels.ServerSocketChannel;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.Set;
import java.util.Collections;
-import jdk.internal.access.JavaNetSocketAccess;
-import jdk.internal.access.SharedSecrets;
import sun.net.PlatformSocketImpl;
/**
@@ -1116,27 +1110,4 @@
}
return options;
}
-
- static {
- SharedSecrets.setJavaNetSocketAccess(
- new JavaNetSocketAccess() {
- @Override
- public ServerSocket newServerSocket(SocketImpl impl) {
- return new ServerSocket(impl);
- }
-
- @Override
- public SocketImpl newSocketImpl(Class<? extends SocketImpl> implClass) {
- try {
- Constructor<? extends SocketImpl> ctor =
- implClass.getDeclaredConstructor();
- return ctor.newInstance();
- } catch (NoSuchMethodException | InstantiationException |
- IllegalAccessException | InvocationTargetException e) {
- throw new AssertionError(e);
- }
- }
- }
- );
- }
}
--- a/src/java.base/share/classes/java/net/URL.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/URL.java Mon Jul 22 11:08:27 2019 +0530
@@ -45,6 +45,7 @@
import jdk.internal.access.JavaNetURLAccess;
import jdk.internal.access.SharedSecrets;
+import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants;
import sun.security.action.GetPropertyAction;
@@ -466,13 +467,19 @@
this.file = path;
}
- // Note: we don't do validation of the URL here. Too risky to change
+ // Note: we don't do full validation of the URL here. Too risky to change
// right now, but worth considering for future reference. -br
if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol);
}
this.handler = handler;
+ if (host != null && isBuiltinStreamHandler(handler)) {
+ String s = IPAddressUtil.checkExternalForm(this);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
+ }
}
/**
@@ -1038,7 +1045,12 @@
* @since 1.5
*/
public URI toURI() throws URISyntaxException {
- return new URI (toString());
+ URI uri = new URI(toString());
+ if (authority != null && isBuiltinStreamHandler(handler)) {
+ String s = IPAddressUtil.checkAuthority(this);
+ if (s != null) throw new URISyntaxException(authority, s);
+ }
+ return uri;
}
/**
@@ -1635,6 +1647,10 @@
return replacementURL;
}
+ boolean isBuiltinStreamHandler(URLStreamHandler handler) {
+ return isBuiltinStreamHandler(handler.getClass().getName());
+ }
+
private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
}
--- a/src/java.base/share/classes/java/net/URLClassLoader.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/URLClassLoader.java Mon Jul 22 11:08:27 2019 +0530
@@ -52,7 +52,6 @@
import jdk.internal.loader.Resource;
import jdk.internal.loader.URLClassPath;
-import jdk.internal.access.JavaNetURLClassLoaderAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.perf.PerfCounter;
import sun.net.www.ParseUtil;
@@ -822,14 +821,6 @@
}
static {
- SharedSecrets.setJavaNetURLClassLoaderAccess(
- new JavaNetURLClassLoaderAccess() {
- @Override
- public AccessControlContext getAccessControlContext(URLClassLoader u) {
- return u.acc;
- }
- }
- );
ClassLoader.registerAsParallelCapable();
}
}
--- a/src/java.base/share/classes/java/net/URLStreamHandler.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/net/URLStreamHandler.java Mon Jul 22 11:08:27 2019 +0530
@@ -516,12 +516,15 @@
* different from this one
* @since 1.3
*/
- protected void setURL(URL u, String protocol, String host, int port,
+ protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String path,
String query, String ref) {
if (this != u.handler) {
throw new SecurityException("handler for url different from " +
"this handler");
+ } else if (host != null && u.isBuiltinStreamHandler(this)) {
+ String s = IPAddressUtil.checkHostString(host);
+ if (s != null) throw new IllegalArgumentException(s);
}
// ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
--- a/src/java.base/share/classes/java/security/AccessController.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/security/AccessController.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -445,7 +445,8 @@
throw new NullPointerException("null permissions parameter");
}
Class<?> caller = Reflection.getCallerClass();
- return AccessController.doPrivileged(action, createWrapper(null,
+ DomainCombiner dc = (context == null) ? null : context.getCombiner();
+ return AccessController.doPrivileged(action, createWrapper(dc,
caller, parent, context, perms));
}
@@ -860,7 +861,8 @@
throw new NullPointerException("null permissions parameter");
}
Class<?> caller = Reflection.getCallerClass();
- return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
+ DomainCombiner dc = (context == null) ? null : context.getCombiner();
+ return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
}
--- a/src/java.base/share/classes/java/util/Collections.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/util/Collections.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package java.util;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
@@ -39,6 +40,7 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import jdk.internal.access.SharedSecrets;
/**
* This class consists exclusively of static methods that operate on or return
@@ -5163,6 +5165,11 @@
public Spliterator<E> spliterator() {
return stream().spliterator();
}
+
+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+ ois.defaultReadObject();
+ SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, n);
+ }
}
/**
--- a/src/java.base/share/classes/java/util/EnumSet.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/util/EnumSet.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,11 +76,12 @@
* @since 1.5
* @see EnumMap
*/
-@SuppressWarnings("serial") // No serialVersionUID due to usage of
- // serial proxy pattern
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
{
+ // declare EnumSet.class serialization compatibility with JDK 8
+ private static final long serialVersionUID = 1009687484059888093L;
+
/**
* The class of all the elements of this set.
*/
--- a/src/java.base/share/classes/java/util/zip/ZipUtils.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,8 +27,6 @@
import java.nio.ByteBuffer;
import java.nio.file.attribute.FileTime;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDateTime;
@@ -278,13 +276,7 @@
* Loads zip native library, if not already laoded
*/
static void loadLibrary() {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null) {
- System.loadLibrary("zip");
- } else {
- PrivilegedAction<Void> pa = () -> { System.loadLibrary("zip"); return null; };
- AccessController.doPrivileged(pa);
- }
+ jdk.internal.loader.BootLoader.loadLibrary("zip");
}
private static final Unsafe unsafe = Unsafe.getUnsafe();
--- a/src/java.base/share/classes/javax/crypto/CipherSpi.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/javax/crypto/CipherSpi.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -761,78 +761,87 @@
+ " bytes of space in output buffer");
}
+ // detecting input and output buffer overlap may be tricky
+ // we can only write directly into output buffer when we
+ // are 100% sure it's safe to do so
+
boolean a1 = input.hasArray();
boolean a2 = output.hasArray();
int total = 0;
- byte[] inArray, outArray;
- if (a2) { // output has an accessible byte[]
- outArray = output.array();
- int outPos = output.position();
- int outOfs = output.arrayOffset() + outPos;
+
+ if (a1) { // input has an accessible byte[]
+ byte[] inArray = input.array();
+ int inOfs = input.arrayOffset() + inPos;
+
+ if (a2) { // output has an accessible byte[]
+ byte[] outArray = output.array();
+ int outPos = output.position();
+ int outOfs = output.arrayOffset() + outPos;
- if (a1) { // input also has an accessible byte[]
- inArray = input.array();
- int inOfs = input.arrayOffset() + inPos;
+ // check array address and offsets and use temp output buffer
+ // if output offset is larger than input offset and
+ // falls within the range of input data
+ boolean useTempOut = false;
+ if (inArray == outArray &&
+ ((inOfs < outOfs) && (outOfs < inOfs + inLen))) {
+ useTempOut = true;
+ outArray = new byte[outLenNeeded];
+ outOfs = 0;
+ }
if (isUpdate) {
total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
} else {
total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
}
+ if (useTempOut) {
+ output.put(outArray, outOfs, total);
+ } else {
+ // adjust output position manually
+ output.position(outPos + total);
+ }
+ // adjust input position manually
input.position(inLimit);
- } else { // input does not have accessible byte[]
- inArray = new byte[getTempArraySize(inLen)];
- do {
- int chunk = Math.min(inLen, inArray.length);
- if (chunk > 0) {
- input.get(inArray, 0, chunk);
- }
- int n;
- if (isUpdate || (inLen > chunk)) {
- n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
- } else {
- n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
- }
- total += n;
- outOfs += n;
- inLen -= chunk;
- } while (inLen > 0);
- }
- output.position(outPos + total);
- } else { // output does not have an accessible byte[]
- if (a1) { // but input has an accessible byte[]
- inArray = input.array();
- int inOfs = input.arrayOffset() + inPos;
+ } else { // output does not have an accessible byte[]
+ byte[] outArray = null;
if (isUpdate) {
outArray = engineUpdate(inArray, inOfs, inLen);
} else {
outArray = engineDoFinal(inArray, inOfs, inLen);
}
- input.position(inLimit);
if (outArray != null && outArray.length != 0) {
output.put(outArray);
total = outArray.length;
}
- } else { // input also does not have an accessible byte[]
- inArray = new byte[getTempArraySize(inLen)];
- do {
- int chunk = Math.min(inLen, inArray.length);
- if (chunk > 0) {
- input.get(inArray, 0, chunk);
- }
- int n;
- if (isUpdate || (inLen > chunk)) {
- outArray = engineUpdate(inArray, 0, chunk);
- } else {
- outArray = engineDoFinal(inArray, 0, chunk);
- }
- if (outArray != null && outArray.length != 0) {
- output.put(outArray);
- total += outArray.length;
- }
- inLen -= chunk;
- } while (inLen > 0);
+ // adjust input position manually
+ input.position(inLimit);
+ }
+ } else { // input does not have an accessible byte[]
+ // have to assume the worst, since we have no way of determine
+ // if input and output overlaps or not
+ byte[] tempOut = new byte[outLenNeeded];
+ int outOfs = 0;
+
+ byte[] tempIn = new byte[getTempArraySize(inLen)];
+ do {
+ int chunk = Math.min(inLen, tempIn.length);
+ if (chunk > 0) {
+ input.get(tempIn, 0, chunk);
+ }
+ int n;
+ if (isUpdate || (inLen > chunk)) {
+ n = engineUpdate(tempIn, 0, chunk, tempOut, outOfs);
+ } else {
+ n = engineDoFinal(tempIn, 0, chunk, tempOut, outOfs);
+ }
+ outOfs += n;
+ total += n;
+ inLen -= chunk;
+ } while (inLen > 0);
+ if (total > 0) {
+ output.put(tempOut, 0, total);
}
}
+
return total;
}
--- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -311,4 +311,12 @@
* @param cause set t's cause to new value
*/
void setCause(Throwable t, Throwable cause);
+
+ /**
+ * Privileged System.loadLibrary
+ *
+ * @param caller on behalf of which the library is being loaded
+ * @param library name of the library to load
+ */
+ void loadLibrary(Class<?> caller, String library);
}
--- a/src/java.base/share/classes/jdk/internal/access/JavaNetSocketAccess.java Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * 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 jdk.internal.access;
-
-import java.net.ServerSocket;
-import java.net.SocketImpl;
-
-public interface JavaNetSocketAccess {
- /**
- * Creates a ServerSocket associated with the given SocketImpl.
- */
- ServerSocket newServerSocket(SocketImpl impl);
-
- /*
- * Constructs a SocketImpl instance of the given class.
- */
- SocketImpl newSocketImpl(Class<? extends SocketImpl> implClass);
-}
--- a/src/java.base/share/classes/jdk/internal/access/JavaNetURLClassLoaderAccess.java Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * 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 jdk.internal.access;
-
-import java.net.URLClassLoader;
-import java.security.AccessControlContext;
-
-public interface JavaNetURLClassLoaderAccess {
- AccessControlContext getAccessControlContext(URLClassLoader u);;
-}
--- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java Mon Jul 22 11:08:27 2019 +0530
@@ -58,10 +58,8 @@
private static JavaIOAccess javaIOAccess;
private static JavaNetInetAddressAccess javaNetInetAddressAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
- private static JavaNetSocketAccess javaNetSocketAccess;
private static JavaNetUriAccess javaNetUriAccess;
private static JavaNetURLAccess javaNetURLAccess;
- private static JavaNetURLClassLoaderAccess javaNetURLClassLoaderAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
@@ -151,16 +149,6 @@
return javaNetURLAccess;
}
- public static void setJavaNetURLClassLoaderAccess(JavaNetURLClassLoaderAccess jnua) {
- javaNetURLClassLoaderAccess = jnua;
- }
-
- public static JavaNetURLClassLoaderAccess getJavaNetURLClassLoaderAccess() {
- if (javaNetURLClassLoaderAccess == null)
- unsafe.ensureClassInitialized(java.net.URLClassLoader.class);
- return javaNetURLClassLoaderAccess;
- }
-
public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
javaNetInetAddressAccess = jna;
}
@@ -181,16 +169,6 @@
return javaNetHttpCookieAccess;
}
- public static void setJavaNetSocketAccess(JavaNetSocketAccess jnsa) {
- javaNetSocketAccess = jnsa;
- }
-
- public static JavaNetSocketAccess getJavaNetSocketAccess() {
- if (javaNetSocketAccess == null)
- unsafe.ensureClassInitialized(java.net.ServerSocket.class);
- return javaNetSocketAccess;
- }
-
public static void setJavaNioAccess(JavaNioAccess jna) {
javaNioAccess = jna;
}
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Mon Jul 22 11:08:27 2019 +0530
@@ -129,6 +129,23 @@
}
/**
+ * Loads a library from the system path.
+ */
+ public static void loadLibrary(String library) {
+ if (System.getSecurityManager() == null) {
+ SharedSecrets.getJavaLangAccess().loadLibrary(BootLoader.class, library);
+ } else {
+ AccessController.doPrivileged(
+ new java.security.PrivilegedAction<>() {
+ public Void run() {
+ SharedSecrets.getJavaLangAccess().loadLibrary(BootLoader.class, library);
+ return null;
+ }
+ });
+ }
+ }
+
+ /**
* Returns a URL to a resource in a module defined to the boot loader.
*/
public static URL findResource(String mn, String name) throws IOException {
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties Mon Jul 22 11:08:27 2019 +0530
@@ -75,7 +75,7 @@
\ -D<name>=<value>\n\
\ set a system property\n\
\ -verbose:[class|module|gc|jni]\n\
-\ enable verbose output\n\
+\ enable verbose output for the given subsystem\n\
\ -version print product version to the error stream and exit\n\
\ --version print product version to the output stream and exit\n\
\ -showversion print product version to the error stream and continue\n\
@@ -129,9 +129,9 @@
\ append to end of bootstrap class path\n\
\ -Xcheck:jni perform additional checks for JNI functions\n\
\ -Xcomp forces compilation of methods on first invocation\n\
-\ -Xdebug provided for backward compatibility\n\
+\ -Xdebug does nothing. Provided for backward compatibility.\n\
\ -Xdiag show additional diagnostic messages\n\
-\ -Xfuture enable strictest checks, anticipating future default\n\
+\ -Xfuture enable strictest checks, anticipating future default.\n\
\ This option is deprecated and may be removed in a\n\
\ future release.\n\
\ -Xint interpreted mode execution only\n\
@@ -141,7 +141,9 @@
\ -Xlog:<opts> Configure or enable logging with the Java Virtual\n\
\ Machine (JVM) unified logging framework. Use -Xlog:help\n\
\ for details.\n\
-\ -Xloggc:<file> log GC status to a file with time stamps\n\
+\ -Xloggc:<file> log GC status to a file with time stamps.\n\
+\ This option is deprecated and may be removed in a\n\
+\ future release. It is replaced by -Xlog:gc:<file>.\n\
\ -Xmixed mixed mode execution (default)\n\
\ -Xmn<size> sets the initial and maximum size (in bytes) of the heap\n\
\ for the young generation (nursery)\n\
@@ -152,6 +154,8 @@
\ -Xshare:auto use shared class data if possible (default)\n\
\ -Xshare:off do not attempt to use shared class data\n\
\ -Xshare:on require using shared class data, otherwise fail.\n\
+\ This is a testing option and may lead to intermittent\n\
+\ failures. It should not be used in production environments.\n\
\ -XshowSettings show all settings and continue\n\
\ -XshowSettings:all\n\
\ show all settings and continue\n\
@@ -191,7 +195,6 @@
\ --patch-module <module>=<file>({0}<file>)*\n\
\ override or augment a module with classes and resources\n\
\ in JAR files or directories.\n\
-\ --disable-@files disable further argument file expansion\n\
\ --source <version>\n\
\ set the version of the source in source-file mode.\n\n\
These extra options are subject to change without notice.\n
@@ -199,7 +202,7 @@
# Translators please note do not translate the options themselves
java.launcher.X.macosx.usage=\
\n\
-The following options are Mac OS X specific:\n\
+The following options are macOS specific:\n\
\ -XstartOnFirstThread\n\
\ run the main() method on the first (AppKit) thread\n\
\ -Xdock:name=<application name>\n\
--- a/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,9 @@
\u6307\u5B9A\u3055\u308C\u305F\u6700\u3082\u9069\u5207\u306A\u30B9\u30B1\u30FC\u30EA\u30F3\u30B0\u6E08\u30A4\u30E1\u30FC\u30B8\u304C\u9078\u629E\u3055\u308C\u307E\u3059\n (\u81EA\u52D5\u7684)\u3002\n \u8A73\u7D30\u306F\u3001SplashScreen API\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\n @argument\u30D5\u30A1\u30A4\u30EB\n \u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u542B\u30801\u3064\u4EE5\u4E0A\u306E\u5F15\u6570\u30D5\u30A1\u30A4\u30EB\n -disable-@files\n \u3055\u3089\u306A\u308B\u5F15\u6570\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u3092\u7121\u52B9\u306B\u3057\u307E\u3059\n --enable-preview\n \u30AF\u30E9\u30B9\u3092\u3053\u306E\u30EA\u30EA\u30FC\u30B9\u306E\u30D7\u30EC\u30D3\u30E5\u30FC\u6A5F\u80FD\u306B\u4F9D\u5B58\u3055\u305B\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\n\u9577\u3044\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u3092\u6307\u5B9A\u3059\u308B\u5834\u5408\u3001--<name>=<value>\u307E\u305F\u306F\n--<name> <value>\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n
# Translators please note do not translate the options themselves
-java.launcher.X.usage=\n -Xbatch \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xbootclasspath/a:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n -Xcheck:jni JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n -Xcomp \u521D\u56DE\u547C\u51FA\u3057\u6642\u306B\u30E1\u30BD\u30C3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u5F37\u5236\u3059\u308B\n -Xdebug \u4E0B\u4F4D\u4E92\u63DB\u6027\u306E\u305F\u3081\u306B\u63D0\u4F9B\n -Xdiag \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n -Xfuture \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xint \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n -Xinternalversion\n -version\u30AA\u30D7\u30B7\u30E7\u30F3\u3088\u308A\u8A73\u7D30\u306AJVM\u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\n \u8868\u793A\u3059\u308B\n -Xloggc:<file> \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n -Xmixed \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xmn<size> \u82E5\u3044\u4E16\u4EE3(\u30CA\u30FC\u30B5\u30EA)\u306E\u30D2\u30FC\u30D7\u306E\u521D\u671F\u304A\u3088\u3073\u6700\u5927\u30B5\u30A4\u30BA(\u30D0\u30A4\u30C8\u5358\u4F4D)\n \u3092\u8A2D\u5B9A\u3059\u308B\n -Xms<size> Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmx<size> Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xnoclassgc \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xrs Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n -Xshare:auto \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xshare:off \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n -Xshare:on \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n -XshowSettings \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:all\n \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:locale\n \u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:properties\n \u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:vm\n \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:system\n (Linux\u306E\u307F) \
-\u30DB\u30B9\u30C8\u30FB\u30B7\u30B9\u30C6\u30E0\u307E\u305F\u306F\u30B3\u30F3\u30C6\u30CA\u306E\n \u69CB\u6210\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -Xss<size> Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xverify \u30D0\u30A4\u30C8\u30B3\u30FC\u30C9\u691C\u8A3C\u6A5F\u80FD\u306E\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3059\u308B\n --add-reads <module>=<target-module>(,<target-module>)*\n \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<target-module>\n \u3092\u8AAD\u307F\u53D6\u308B\u3002 \n <target-module>\u3092ALL-UNNAMED\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n \u8AAD\u307F\u53D6\u308C\u307E\u3059\u3002\n --add-exports <module>/<package>=<target-module>(,<target-module>)*\n \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<package>\u3092<target-module>\u306B\n \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\u3002\n <target-module>\u3092ALL-UNNAMED\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\n \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3067\u304D\u307E\u3059\u3002\n --add-opens <module>/<package>=<target-module>(,<target-module>)*\n \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066\n <package>\u3092<target-module>\u306B\u958B\u304F\u3002\n --illegal-access=<value>\n \u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u5185\u306E\u30B3\u30FC\u30C9\u306B\u3088\u308B\u3001\u540D\u524D\u306E\u3042\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u5185\u306E\n \u30BF\u30A4\u30D7\u306E\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u3092\u8A31\u53EF\u307E\u305F\u306F\u62D2\u5426\u3059\u308B\u3002\n <value>\u306F"deny"\u3001"permit"\u3001"warn"\u3001"debug"\u306E\u3044\u305A\u308C\u304B\u3067\u3059\n \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u307E\u3059\u3002\n --limit-modules <module name>[,<module name>...]\n \u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3059\u308B\n --patch-module <module>=<file>({0}<file>)*\n JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\n \u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3059\u308B\u3002\n --disable-@files \u3055\u3089\u306A\u308B\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u3092\u7121\u52B9\u306B\u3059\u308B\n --source <version>\n \u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u30FB\u30E2\u30FC\u30C9\u3067\u30BD\u30FC\u30B9\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u8A2D\u5B9A\u3059\u308B\u3002\n\n\u3053\u308C\u3089\u306F\u8FFD\u52A0\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\n
+java.launcher.X.usage=\n -Xbatch \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u30FB\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3057\u307E\u3059\n -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3057\u307E\u3059\n -Xcheck:jni JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3057\u307E\u3059\n -Xcomp \u521D\u56DE\u547C\u51FA\u3057\u6642\u306B\u30E1\u30BD\u30C3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u5F37\u5236\u3057\u307E\u3059\n -Xdebug \u4E0B\u4F4D\u4E92\u63DB\u6027\u306E\u305F\u3081\u306B\u7528\u610F\u3055\u308C\u3066\u3044\u307E\u3059\n -Xdiag \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u307E\u3059\n -Xfuture \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3057\u307E\u3059\n \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u63A8\u5968\u3067\u3042\u308A\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\n \u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\n -Xint \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n -Xinternalversion\n -version\u30AA\u30D7\u30B7\u30E7\u30F3\u3088\u308A\u8A73\u7D30\u306AJVM\u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\n \u8868\u793A\u3057\u307E\u3059\n -Xlog:<opts> Java Virtual Machine (JVM)\u7D71\u5408\u30ED\u30AE\u30F3\u30B0\u30FB\u30D5\u30EC\u30FC\u30E0\u30EF\u30FC\u30AF\u3067\u306E\n \u30ED\u30AE\u30F3\u30B0\u3092\u69CB\u6210\u307E\u305F\u306F\u6709\u52B9\u5316\u3057\u307E\u3059\u3002\u8A73\u7D30\u306F\u3001-Xlog:help\u3092\n \u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n -Xloggc:<file> \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3057\u307E\u3059\n -Xmixed \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xmn<size> \u82E5\u3044\u4E16\u4EE3(\u30CA\u30FC\u30B5\u30EA)\u306E\u30D2\u30FC\u30D7\u306E\u521D\u671F\u30B5\u30A4\u30BA\u304A\u3088\u3073\u6700\u5927\u30B5\u30A4\u30BA\n (\u30D0\u30A4\u30C8\u5358\u4F4D)\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n -Xms<size> Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n -Xmx<size> Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n -Xnoclassgc \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3057\u307E\u3059\n -Xrs Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3057\u307E\u3059(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n -Xshare:auto \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xshare:off \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u8A66\u307F\u307E\u305B\u3093\n -Xshare:on \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3057\u307E\u3059\u3002\n -XshowSettings \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3057\u307E\u3059\n -XshowSettings:all\n \
+ \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3057\u307E\u3059\n -XshowSettings:locale\n \u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3057\u307E\u3059\n -XshowSettings:properties\n \u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3057\u307E\u3059\n -XshowSettings:vm\n \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3057\u307E\u3059\n -XshowSettings:system\n (Linux\u306E\u307F)\u30DB\u30B9\u30C8\u30FB\u30B7\u30B9\u30C6\u30E0\u307E\u305F\u306F\u30B3\u30F3\u30C6\u30CA\u3092\u8868\u793A\u3057\u307E\u3059\n \u69CB\u6210\u3057\u3066\u7D9A\u884C\u3057\u307E\u3059\n -Xss<size> java\u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n -Xverify \u30D0\u30A4\u30C8\u30B3\u30FC\u30C9\u30FB\u30D9\u30EA\u30D5\u30A1\u30A4\u30A2\u306E\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n \u30AA\u30D7\u30B7\u30E7\u30F3-Xverify:none\u306F\u975E\u63A8\u5968\u306B\u306A\u308A\u3001\n \u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\n --add-reads <module>=<target-module>(,<target-module>)*\n \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<target-module>\u3092\n \u8AAD\u307F\u53D6\u308A\u307E\u3059\u3002 \n <target-module>\u3092ALL-UNNAMED\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n \u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002\n --add-exports <module>/<package>=<target-module>(,<target-module>)*\n \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<package>\u3092<target-module>\u306B\n \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\n <target-module>\u3092ALL-UNNAMED\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\n \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3067\u304D\u307E\u3059\u3002\n --add-opens <module>/<package>=<target-module>(,<target-module>)*\n \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<package>\u3092\n <target-module>\u306B\u958B\u304D\u307E\u3059\u3002\n --illegal-access=<value>\n \u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u5185\u306E\u30B3\u30FC\u30C9\u306B\u3088\u308B\u3001\u540D\u524D\u306E\u3042\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u5185\u306E\u30BF\u30A4\u30D7\u306E\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u4E0D\u6B63\u30A2\u30AF\u30BB\u30B9\u3092\n \u8A31\u53EF\u307E\u305F\u306F\u62D2\u5426\u3057\u307E\u3059\u3002\n <value>\u306F"deny"\u3001"permit"\u3001"warn"\u307E\u305F\u306F"debug"\u306E\u3044\u305A\u308C\u304B\u3067\u3059\n \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059\u3002\n --limit-modules <module name>[,<module name>...]\n \u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3057\u307E\u3059\n --patch-module <module>=<file>({0}<file>)*\n \
+JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\n \u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3057\u307E\u3059\u3002\n --disable-@files\u306F\u3001\u3055\u3089\u306A\u308B\u5F15\u6570\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u3092\u7121\u52B9\u306B\u3057\u307E\u3059\n --source <version>\n \u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u30FB\u30E2\u30FC\u30C9\u3067\u30BD\u30FC\u30B9\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n\u3053\u306E\u8FFD\u52A0\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\n
# Translators please note do not translate the options themselves
java.launcher.X.macosx.usage=\n\u6B21\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306FMac OS X\u56FA\u6709\u3067\u3059:\n -XstartOnFirstThread\n main()\u30E1\u30BD\u30C3\u30C9\u3092\u6700\u521D(AppKit)\u306E\u30B9\u30EC\u30C3\u30C9\u3067\u5B9F\u884C\u3059\u308B\n -Xdock:name=<application name>\n Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -Xdock:icon=<path to icon file>\n Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n\n
@@ -58,4 +59,4 @@
java.launcher.module.error2=\u30A8\u30E9\u30FC: \u30E2\u30B8\u30E5\u30FC\u30EB{1}\u306B\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u304B\u30ED\u30FC\u30C9\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
java.launcher.module.error3=\u30A8\u30E9\u30FC: \u30E2\u30B8\u30E5\u30FC\u30EB{1}\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9{0}\u3092\u30ED\u30FC\u30C9\u3067\u304D\u307E\u305B\u3093\n\t{2}
java.launcher.module.error4={0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-java.launcher.module.error5=\u30A8\u30E9\u30FC: \u30E2\u30B8\u30E5\u30FC\u30EB{1}\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9{0}\u3092\u521D\u671F\u5316\u3067\u304D\u307E\u305B\u3093\n\u539F\u56E0: {1}: {2}
+java.launcher.module.error5=\u30A8\u30E9\u30FC: \u30E2\u30B8\u30E5\u30FC\u30EB{1}\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9{0}\u3092\u521D\u671F\u5316\u3067\u304D\u307E\u305B\u3093\n\u539F\u56E0: {2}: {3}
--- a/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,8 @@
| -enablesystemassertions\n \u542F\u7528\u7CFB\u7EDF\u65AD\u8A00\n -dsa | -disablesystemassertions\n \u7981\u7528\u7CFB\u7EDF\u65AD\u8A00\n -agentlib:<\u5E93\u540D>[=<\u9009\u9879>]\n \u52A0\u8F7D\u672C\u673A\u4EE3\u7406\u5E93 <\u5E93\u540D>, \u4F8B\u5982 -agentlib:jdwp\n \u53E6\u8BF7\u53C2\u9605 -agentlib:jdwp=help\n -agentpath:<\u8DEF\u5F84\u540D>[=<\u9009\u9879>]\n \u6309\u5B8C\u6574\u8DEF\u5F84\u540D\u52A0\u8F7D\u672C\u673A\u4EE3\u7406\u5E93\n -javaagent:<jar \u8DEF\u5F84>[=<\u9009\u9879>]\n \u52A0\u8F7D Java \u7F16\u7A0B\u8BED\u8A00\u4EE3\u7406, \u8BF7\u53C2\u9605 java.lang.instrument\n -splash:<\u56FE\u50CF\u8DEF\u5F84>\n \u4F7F\u7528\u6307\u5B9A\u7684\u56FE\u50CF\u663E\u793A\u542F\u52A8\u5C4F\u5E55\n \u81EA\u52A8\u652F\u6301\u548C\u4F7F\u7528 HiDPI \u7F29\u653E\u56FE\u50CF\n (\u5982\u679C\u53EF\u7528)\u3002\u5E94\u59CB\u7EC8\u5C06\u672A\u7F29\u653E\u7684\u56FE\u50CF\u6587\u4EF6\u540D (\u4F8B\u5982, image.ext)\n \u4F5C\u4E3A\u53C2\u6570\u4F20\u9012\u7ED9 -splash \u9009\u9879\u3002\n \u5C06\u81EA\u52A8\u9009\u53D6\u63D0\u4F9B\u7684\u6700\u5408\u9002\u7684\u7F29\u653E\n \u56FE\u50CF\u3002\n \u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u53C2\u9605 SplashScreen API \u6587\u6863\n @argument \u6587\u4EF6\n \u4E00\u4E2A\u6216\u591A\u4E2A\u5305\u542B\u9009\u9879\u7684\u53C2\u6570\u6587\u4EF6\n -disable-@files\n \u963B\u6B62\u8FDB\u4E00\u6B65\u6269\u5C55\u53C2\u6570\u6587\u4EF6\n --enable-preview\n \u5141\u8BB8\u7C7B\u4F9D\u8D56\u4E8E\u6B64\u53D1\u884C\u7248\u7684\u9884\u89C8\u529F\u80FD\n\u8981\u4E3A\u957F\u9009\u9879\u6307\u5B9A\u53C2\u6570, \u53EF\u4EE5\u4F7F\u7528 --<\u540D\u79F0>=<\u503C> \u6216\n--<\u540D\u79F0> <\u503C>\u3002\n
# Translators please note do not translate the options themselves
-java.launcher.X.usage=\n -Xbatch \u7981\u7528\u540E\u53F0\u7F16\u8BD1\n -Xbootclasspath/a:<\u4EE5 {0} \u5206\u9694\u7684\u76EE\u5F55\u548C zip/jar \u6587\u4EF6>\n \u9644\u52A0\u5728\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u672B\u5C3E\n -Xcheck:jni \u5BF9 JNI \u51FD\u6570\u6267\u884C\u5176\u4ED6\u68C0\u67E5\n -Xcomp \u5728\u9996\u6B21\u8C03\u7528\u65F6\u5F3A\u5236\u7F16\u8BD1\u65B9\u6CD5\n -Xdebug \u4E3A\u5B9E\u73B0\u5411\u540E\u517C\u5BB9\u800C\u63D0\u4F9B\n -Xdiag \u663E\u793A\u9644\u52A0\u8BCA\u65AD\u6D88\u606F\n -Xfuture \u542F\u7528\u6700\u4E25\u683C\u7684\u68C0\u67E5\uFF0C\u9884\u671F\u5C06\u6765\u7684\u9ED8\u8BA4\u503C\n -Xint \u4EC5\u89E3\u91CA\u6A21\u5F0F\u6267\u884C\n -Xinternalversion\n \u663E\u793A\u6BD4 -version \u9009\u9879\u66F4\u8BE6\u7EC6\u7684 JVM\n \u7248\u672C\u4FE1\u606F\n -Xloggc:<\u6587\u4EF6> \u5C06 GC \u72B6\u6001\u8BB0\u5F55\u5728\u6587\u4EF6\u4E2D\uFF08\u5E26\u65F6\u95F4\u6233\uFF09\n -Xmixed \u6DF7\u5408\u6A21\u5F0F\u6267\u884C\uFF08\u9ED8\u8BA4\u503C\uFF09\n -Xmn<\u5927\u5C0F> \u4E3A\u5E74\u8F7B\u4EE3\uFF08\u65B0\u751F\u4EE3\uFF09\u8BBE\u7F6E\u521D\u59CB\u548C\u6700\u5927\u5806\u5927\u5C0F\n \uFF08\u4EE5\u5B57\u8282\u4E3A\u5355\u4F4D\uFF09\n -Xms<\u5927\u5C0F> \u8BBE\u7F6E\u521D\u59CB Java \u5806\u5927\u5C0F\n -Xmx<\u5927\u5C0F> \u8BBE\u7F6E\u6700\u5927 Java \u5806\u5927\u5C0F\n -Xnoclassgc \u7981\u7528\u7C7B\u5783\u573E\u6536\u96C6\n -Xrs \u51CF\u5C11 Java/VM \u5BF9\u64CD\u4F5C\u7CFB\u7EDF\u4FE1\u53F7\u7684\u4F7F\u7528\uFF08\u8BF7\u53C2\u89C1\u6587\u6863\uFF09\n -Xshare:auto \u5728\u53EF\u80FD\u7684\u60C5\u51B5\u4E0B\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\uFF08\u9ED8\u8BA4\u503C\uFF09\n -Xshare:off \u4E0D\u5C1D\u8BD5\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\n -Xshare:on \u8981\u6C42\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\uFF0C\u5426\u5219\u5C06\u5931\u8D25\u3002\n -XshowSettings \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:all\n \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:locale\n \u663E\u793A\u6240\u6709\u4E0E\u533A\u57DF\u8BBE\u7F6E\u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:properties\n \u663E\u793A\u6240\u6709\u5C5E\u6027\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:vm\n \u663E\u793A\u6240\u6709\u4E0E vm \u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:system\n \uFF08\u4EC5 Linux\uFF09\u663E\u793A\u4E3B\u673A\u7CFB\u7EDF\u6216\u5BB9\u5668\n \u914D\u7F6E\u5E76\u7EE7\u7EED\n -Xss<\u5927\u5C0F> \u8BBE\u7F6E Java \u7EBF\u7A0B\u5806\u6808\u5927\u5C0F\n -Xverify \u8BBE\u7F6E\u5B57\u8282\u7801\u9A8C\u8BC1\u5668\u7684\u6A21\u5F0F\n --add-reads <\u6A21\u5757>=<\u76EE\u6807\u6A21\u5757>(,<\u76EE\u6807\u6A21\u5757>)*\n \u66F4\u65B0 <\u6A21\u5757> \u4EE5\u8BFB\u53D6 <\u76EE\u6807\u6A21\u5757>\uFF0C\u800C\u65E0\u8BBA\n \u6A21\u5757\u58F0\u660E\u5982\u4F55\u3002\n <\u76EE\u6807\u6A21\u5757> \u53EF\u4EE5\u662F ALL-UNNAMED \u4EE5\u8BFB\u53D6\u6240\u6709\u672A\u547D\u540D\n \u6A21\u5757\u3002\n --add-exports <\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u76EE\u6807\u6A21\u5757>(,<\u76EE\u6807\u6A21\u5757>)*\n \u66F4\u65B0 <\u6A21\u5757> \u4EE5\u5C06 <\u7A0B\u5E8F\u5305> \u5BFC\u51FA\u5230 <\u76EE\u6807\u6A21\u5757>\uFF0C\n \u800C\u65E0\u8BBA\u6A21\u5757\u58F0\u660E\u5982\u4F55\u3002\n <\u76EE\u6807\u6A21\u5757> \u53EF\u4EE5\u662F ALL-UNNAMED \u4EE5\u5BFC\u51FA\u5230\u6240\u6709\n \
-\u672A\u547D\u540D\u6A21\u5757\u3002\n --add-opens <\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u76EE\u6807\u6A21\u5757>(,<\u76EE\u6807\u6A21\u5757>)*\n \u66F4\u65B0 <\u6A21\u5757> \u4EE5\u5728 <\u76EE\u6807\u6A21\u5757> \u4E2D\u6253\u5F00\n <\u7A0B\u5E8F\u5305>\uFF0C\u800C\u65E0\u8BBA\u6A21\u5757\u58F0\u660E\u5982\u4F55\u3002\n --illegal-access=<\u503C>\n \u5141\u8BB8\u6216\u62D2\u7EDD\u901A\u8FC7\u672A\u547D\u540D\u6A21\u5757\u4E2D\u7684\u4EE3\u7801\u5BF9\u547D\u540D\u6A21\u5757\u4E2D\u7684\n \u7C7B\u578B\u6210\u5458\u8FDB\u884C\u8BBF\u95EE\u3002\n <\u503C> \u4E3A "deny"\u3001"permit"\u3001"warn" \u6216 "debug" \u4E4B\u4E00\n \u6B64\u9009\u9879\u5C06\u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664\u3002\n --limit-modules <\u6A21\u5757\u540D>[,<\u6A21\u5757\u540D>...]\n \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF\n --patch-module <\u6A21\u5757>=<\u6587\u4EF6>({0}<\u6587\u4EF6>)*\n \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\n \u8986\u76D6\u6216\u589E\u5F3A\u6A21\u5757\u3002\n --disable-@files \u7981\u6B62\u8FDB\u4E00\u6B65\u6269\u5C55\u53C2\u6570\u6587\u4EF6\n --source <\u7248\u672C>\n \u8BBE\u7F6E\u6E90\u6587\u4EF6\u6A21\u5F0F\u4E2D\u6E90\u7684\u7248\u672C\u3002\n\n\u8FD9\u4E9B\u989D\u5916\u9009\u9879\u5982\u6709\u66F4\u6539\uFF0C\u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
+java.launcher.X.usage=\n -Xbatch \u7981\u7528\u540E\u53F0\u7F16\u8BD1\n -Xbootclasspath/a:<\u4EE5 {0} \u5206\u9694\u7684\u76EE\u5F55\u548C zip/jar \u6587\u4EF6>\n \u9644\u52A0\u5728\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u672B\u5C3E\n -Xcheck:jni \u5BF9 JNI \u51FD\u6570\u6267\u884C\u5176\u4ED6\u68C0\u67E5\n -Xcomp \u5F3A\u5236\u5728\u9996\u6B21\u8C03\u7528\u65F6\u7F16\u8BD1\u65B9\u6CD5\n -Xdebug \u4E3A\u5B9E\u73B0\u5411\u540E\u517C\u5BB9\u800C\u63D0\u4F9B\n -Xdiag \u663E\u793A\u9644\u52A0\u8BCA\u65AD\u6D88\u606F\n -Xfuture \u542F\u7528\u6700\u4E25\u683C\u7684\u68C0\u67E5\uFF0C\u9884\u671F\u5C06\u6765\u7684\u9ED8\u8BA4\u503C\n \u6B64\u9009\u9879\u5DF2\u8FC7\u65F6\uFF0C\u53EF\u80FD\u4F1A\u5728\n \u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664\u3002\n -Xint \u4EC5\u89E3\u91CA\u6A21\u5F0F\u6267\u884C\n -Xinternalversion\n \u663E\u793A\u6BD4 -version \u9009\u9879\u66F4\u8BE6\u7EC6\u7684\n JVM \u7248\u672C\u4FE1\u606F\n -Xlog:<opts> \u914D\u7F6E\u6216\u542F\u7528\u91C7\u7528 Java \u865A\u62DF\n \u673A (Java Virtual Machine, JVM) \u7EDF\u4E00\u8BB0\u5F55\u6846\u67B6\u8FDB\u884C\u4E8B\u4EF6\u8BB0\u5F55\u3002\u4F7F\u7528 -Xlog:help\n \u53EF\u4E86\u89E3\u8BE6\u7EC6\u4FE1\u606F\u3002\n -Xloggc:<file> \u5C06 GC \u72B6\u6001\u8BB0\u5F55\u5728\u6587\u4EF6\u4E2D\uFF08\u5E26\u65F6\u95F4\u6233\uFF09\n -Xmixed \u6DF7\u5408\u6A21\u5F0F\u6267\u884C\uFF08\u9ED8\u8BA4\u503C\uFF09\n -Xmn<size> \u4E3A\u5E74\u8F7B\u4EE3\uFF08\u65B0\u751F\u4EE3\uFF09\u8BBE\u7F6E\u521D\u59CB\u548C\u6700\u5927\u5806\u5927\u5C0F\n \uFF08\u4EE5\u5B57\u8282\u4E3A\u5355\u4F4D\uFF09\n -Xms<size> \u8BBE\u7F6E\u521D\u59CB Java \u5806\u5927\u5C0F\n -Xmx<size> \u8BBE\u7F6E\u6700\u5927 Java \u5806\u5927\u5C0F\n -Xnoclassgc \u7981\u7528\u7C7B\u5783\u573E\u6536\u96C6\n -Xrs \u51CF\u5C11 Java/VM \u5BF9\u64CD\u4F5C\u7CFB\u7EDF\u4FE1\u53F7\u7684\u4F7F\u7528\uFF08\u8BF7\u53C2\u89C1\u6587\u6863\uFF09\n -Xshare:auto \u5728\u53EF\u80FD\u7684\u60C5\u51B5\u4E0B\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\uFF08\u9ED8\u8BA4\u503C\uFF09\n -Xshare:off \u4E0D\u5C1D\u8BD5\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\n -Xshare:on \u8981\u6C42\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\uFF0C\u5426\u5219\u5C06\u5931\u8D25\u3002\n -XshowSettings \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:all\n \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:locale\n \u663E\u793A\u6240\u6709\u4E0E\u533A\u57DF\u8BBE\u7F6E\u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:properties\n \u663E\u793A\u6240\u6709\u5C5E\u6027\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:vm\n \u663E\u793A\u6240\u6709\u4E0E vm \u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n -XshowSettings:system\n \uFF08\u4EC5 Linux\uFF09\u663E\u793A\u4E3B\u673A\u7CFB\u7EDF\u6216\u5BB9\u5668\n \u914D\u7F6E\u5E76\u7EE7\u7EED\n -Xss<size> \u8BBE\u7F6E Java \u7EBF\u7A0B\u5806\u6808\u5927\u5C0F\n -Xverify \u8BBE\u7F6E\u5B57\u8282\u7801\u9A8C\u8BC1\u5668\u7684\u6A21\u5F0F\n \u8BF7\u6CE8\u610F\uFF0C\u9009\u9879 -Xverify:none \u5DF2\u8FC7\u65F6\uFF0C\n \u53EF\u80FD\u4F1A\u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664\u3002\n --add-reads <module>=<target-module>(,<target-module>)*\n \u66F4\u65B0 <module> \u4EE5\u8BFB\u53D6 <target-module>\uFF0C\u800C\u65E0\u8BBA\n \u6A21\u5757\u5982\u4F55\u58F0\u660E\u3002 \n <target-module> \u53EF\u4EE5\u662F \
+ALL-UNNAMED\uFF0C\u5C06\u8BFB\u53D6\u6240\u6709\u672A\u547D\u540D\n \u6A21\u5757\u3002\n --add-exports <module>/<package>=<target-module>(,<target-module>)*\n \u66F4\u65B0 <module> \u4EE5\u5C06 <package> \u5BFC\u51FA\u5230 <target-module>\uFF0C\n \u800C\u65E0\u8BBA\u6A21\u5757\u5982\u4F55\u58F0\u660E\u3002\n <target-module> \u53EF\u4EE5\u662F ALL-UNNAMED\uFF0C\u5C06\u5BFC\u51FA\u5230\u6240\u6709\n \u672A\u547D\u540D\u6A21\u5757\u3002\n --add-opens <module>/<package>=<target-module>(,<target-module>)*\n \u66F4\u65B0 <module> \u4EE5\u5728 <target-module> \u4E2D\u6253\u5F00\n <package>\uFF0C\u800C\u65E0\u8BBA\u6A21\u5757\u5982\u4F55\u58F0\u660E\u3002\n --illegal-access=<value>\n \u5141\u8BB8\u6216\u62D2\u7EDD\u901A\u8FC7\u672A\u547D\u540D\u6A21\u5757\u4E2D\u7684\u4EE3\u7801\u5BF9\u547D\u540D\u6A21\u5757\u4E2D\u7684\n \u7C7B\u578B\u6210\u5458\u8FDB\u884C\u8BBF\u95EE\u3002\n <value> \u4E3A "deny"\u3001"permit"\u3001"warn" \u6216 "debug" \u4E4B\u4E00\n \u6B64\u9009\u9879\u5C06\u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664\u3002\n --limit-modules <module name>[,<module name>...]\n \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF\n --patch-module <module>=<file>({0}<file>)*\n \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\n \u8986\u76D6\u6216\u589E\u5F3A\u6A21\u5757\u3002\n --disable-@files \u7981\u6B62\u8FDB\u4E00\u6B65\u6269\u5C55\u53C2\u6570\u6587\u4EF6\n --source <version>\n \u8BBE\u7F6E\u6E90\u6587\u4EF6\u6A21\u5F0F\u4E2D\u6E90\u7684\u7248\u672C\u3002\n\n\u8FD9\u4E9B\u989D\u5916\u9009\u9879\u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
# Translators please note do not translate the options themselves
java.launcher.X.macosx.usage=\n\u4EE5\u4E0B\u9009\u9879\u4E3A Mac OS X \u7279\u5B9A\u7684\u9009\u9879:\n -XstartOnFirstThread\n \u5728\u7B2C\u4E00\u4E2A (AppKit) \u7EBF\u7A0B\u4E0A\u8FD0\u884C main() \u65B9\u6CD5\n -Xdock:name=<\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0>\n \u8986\u76D6\u505C\u9760\u680F\u4E2D\u663E\u793A\u7684\u9ED8\u8BA4\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0\n -Xdock:icon=<\u56FE\u6807\u6587\u4EF6\u7684\u8DEF\u5F84>\n \u8986\u76D6\u505C\u9760\u680F\u4E2D\u663E\u793A\u7684\u9ED8\u8BA4\u56FE\u6807\n\n
@@ -57,4 +57,4 @@
java.launcher.module.error2=\u9519\u8BEF: \u5728\u6A21\u5757 {1} \u4E2D\u627E\u4E0D\u5230\u6216\u65E0\u6CD5\u52A0\u8F7D\u4E3B\u7C7B {0}
java.launcher.module.error3=\u9519\u8BEF: \u65E0\u6CD5\u5C06\u4E3B\u7C7B {0} \u52A0\u8F7D\u5230\u6A21\u5757 {1} \u4E2D\n\t{2}
java.launcher.module.error4=\u627E\u4E0D\u5230{0}
-java.launcher.module.error5=\u9519\u8BEF: \u65E0\u6CD5\u521D\u59CB\u5316\u6A21\u5757 {1} \u4E2D\u7684\u4E3B\u7C7B {0}\n\u539F\u56E0: {1}: {2}
+java.launcher.module.error5=\u9519\u8BEF: \u65E0\u6CD5\u521D\u59CB\u5316\u6A21\u5757 {1} \u4E2D\u7684\u4E3B\u7C7B {0}\n\u539F\u56E0: {2}: {3}
--- a/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,8 +29,8 @@
import java.net.SocketException;
import java.net.SocketOption;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* Defines the infrastructure to support extended socket options, beyond those
@@ -45,6 +45,9 @@
public static final short SOCK_DGRAM = 2;
private final Set<SocketOption<?>> options;
+ private final Set<SocketOption<?>> datagramOptions;
+ private final Set<SocketOption<?>> clientStreamOptions;
+ private final Set<SocketOption<?>> serverStreamOptions;
/** Tells whether or not the option is supported. */
public final boolean isOptionSupported(SocketOption<?> option) {
@@ -78,11 +81,11 @@
return getInstance().options0(SOCK_DGRAM, false);
}
- private boolean isDatagramOption(SocketOption<?> option) {
+ private static boolean isDatagramOption(SocketOption<?> option) {
return !option.name().startsWith("TCP_");
}
- private boolean isStreamOption(SocketOption<?> option, boolean server) {
+ private static boolean isStreamOption(SocketOption<?> option, boolean server) {
if (server && "SO_FLOW_SLA".equals(option.name())) {
return false;
} else {
@@ -91,23 +94,19 @@
}
private Set<SocketOption<?>> options0(short type, boolean server) {
- Set<SocketOption<?>> extOptions;
switch (type) {
case SOCK_DGRAM:
- extOptions = options.stream()
- .filter(option -> isDatagramOption(option))
- .collect(Collectors.toUnmodifiableSet());
- break;
+ return datagramOptions;
case SOCK_STREAM:
- extOptions = options.stream()
- .filter(option -> isStreamOption(option, server))
- .collect(Collectors.toUnmodifiableSet());
- break;
+ if (server) {
+ return serverStreamOptions;
+ } else {
+ return clientStreamOptions;
+ }
default:
//this will never happen
throw new IllegalArgumentException("Invalid socket option type");
}
- return extOptions;
}
/** Sets the value of a socket option, for the given socket. */
@@ -120,6 +119,23 @@
protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
this.options = options;
+ var datagramOptions = new HashSet<SocketOption<?>>();
+ var serverStreamOptions = new HashSet<SocketOption<?>>();
+ var clientStreamOptions = new HashSet<SocketOption<?>>();
+ for (var option : options) {
+ if (isDatagramOption(option)) {
+ datagramOptions.add(option);
+ }
+ if (isStreamOption(option, true)) {
+ serverStreamOptions.add(option);
+ }
+ if (isStreamOption(option, false)) {
+ clientStreamOptions.add(option);
+ }
+ }
+ this.datagramOptions = Set.copyOf(datagramOptions);
+ this.serverStreamOptions = Set.copyOf(serverStreamOptions);
+ this.clientStreamOptions = Set.copyOf(clientStreamOptions);
}
private static volatile ExtendedSocketOptions instance;
--- a/src/java.base/share/classes/sun/net/sdp/SdpSupport.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/sdp/SdpSupport.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* 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.IOException;
import java.io.FileDescriptor;
-import java.security.AccessController;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaIOFileDescriptorAccess;
@@ -75,12 +74,6 @@
private static native void convert0(int fd) throws IOException;
static {
- AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
}
}
--- a/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,13 +98,7 @@
return NetProperties.getBoolean(key);
}});
if (b != null && b.booleanValue()) {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
hasSystemProxies = init();
}
}
--- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java Mon Jul 22 11:08:27 2019 +0530
@@ -32,9 +32,11 @@
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@@ -372,4 +374,181 @@
return null;
}
}
+
+ // See java.net.URI for more details on how to generate these
+ // masks.
+ //
+ // square brackets
+ private static final long L_IPV6_DELIMS = 0x0L; // "[]"
+ private static final long H_IPV6_DELIMS = 0x28000000L; // "[]"
+ // RFC 3986 gen-delims
+ private static final long L_GEN_DELIMS = 0x8400800800000000L; // ":/?#[]@"
+ private static final long H_GEN_DELIMS = 0x28000001L; // ":/?#[]@"
+ // These gen-delims can appear in authority
+ private static final long L_AUTH_DELIMS = 0x400000000000000L; // "@[]:"
+ private static final long H_AUTH_DELIMS = 0x28000001L; // "@[]:"
+ // colon is allowed in userinfo
+ private static final long L_COLON = 0x400000000000000L; // ":"
+ private static final long H_COLON = 0x0L; // ":"
+ // slash should be encoded in authority
+ private static final long L_SLASH = 0x800000000000L; // "/"
+ private static final long H_SLASH = 0x0L; // "/"
+ // backslash should always be encoded
+ private static final long L_BACKSLASH = 0x0L; // "\"
+ private static final long H_BACKSLASH = 0x10000000L; // "\"
+ // ASCII chars 0-31 + 127 - various controls + CRLF + TAB
+ private static final long L_NON_PRINTABLE = 0xffffffffL;
+ private static final long H_NON_PRINTABLE = 0x8000000000000000L;
+ // All of the above
+ private static final long L_EXCLUDE = 0x84008008ffffffffL;
+ private static final long H_EXCLUDE = 0x8000000038000001L;
+
+ private static final char[] OTHERS = {
+ 8263,8264,8265,8448,8449,8453,8454,10868,
+ 65109,65110,65119,65131,65283,65295,65306,65311,65312
+ };
+
+ // Tell whether the given character is found by the given mask pair
+ public static boolean match(char c, long lowMask, long highMask) {
+ if (c < 64)
+ return ((1L << c) & lowMask) != 0;
+ if (c < 128)
+ return ((1L << (c - 64)) & highMask) != 0;
+ return false; // other non ASCII characters are not filtered
+ }
+
+ // returns -1 if the string doesn't contain any characters
+ // from the mask, the index of the first such character found
+ // otherwise.
+ public static int scan(String s, long lowMask, long highMask) {
+ int i = -1, len;
+ if (s == null || (len = s.length()) == 0) return -1;
+ boolean match = false;
+ while (++i < len && !(match = match(s.charAt(i), lowMask, highMask)));
+ if (match) return i;
+ return -1;
+ }
+
+ public static int scan(String s, long lowMask, long highMask, char[] others) {
+ int i = -1, len;
+ if (s == null || (len = s.length()) == 0) return -1;
+ boolean match = false;
+ char c, c0 = others[0];
+ while (++i < len && !(match = match((c=s.charAt(i)), lowMask, highMask))) {
+ if (c >= c0 && (Arrays.binarySearch(others, c) > -1)) {
+ match = true; break;
+ }
+ }
+ if (match) return i;
+
+ return -1;
+ }
+
+ private static String describeChar(char c) {
+ if (c < 32 || c == 127) {
+ if (c == '\n') return "LF";
+ if (c == '\r') return "CR";
+ return "control char (code=" + (int)c + ")";
+ }
+ if (c == '\\') return "'\\'";
+ return "'" + c + "'";
+ }
+
+ private static String checkUserInfo(String str) {
+ // colon is permitted in user info
+ int index = scan(str, L_EXCLUDE & ~L_COLON,
+ H_EXCLUDE & ~H_COLON);
+ if (index >= 0) {
+ return "Illegal character found in user-info: "
+ + describeChar(str.charAt(index));
+ }
+ return null;
+ }
+
+ private static String checkHost(String str) {
+ int index;
+ if (str.startsWith("[") && str.endsWith("]")) {
+ str = str.substring(1, str.length() - 1);
+ if (isIPv6LiteralAddress(str)) {
+ index = str.indexOf('%');
+ if (index >= 0) {
+ index = scan(str = str.substring(index),
+ L_NON_PRINTABLE | L_IPV6_DELIMS,
+ H_NON_PRINTABLE | H_IPV6_DELIMS);
+ if (index >= 0) {
+ return "Illegal character found in IPv6 scoped address: "
+ + describeChar(str.charAt(index));
+ }
+ }
+ return null;
+ }
+ return "Unrecognized IPv6 address format";
+ } else {
+ index = scan(str, L_EXCLUDE, H_EXCLUDE);
+ if (index >= 0) {
+ return "Illegal character found in host: "
+ + describeChar(str.charAt(index));
+ }
+ }
+ return null;
+ }
+
+ private static String checkAuth(String str) {
+ int index = scan(str,
+ L_EXCLUDE & ~L_AUTH_DELIMS,
+ H_EXCLUDE & ~H_AUTH_DELIMS);
+ if (index >= 0) {
+ return "Illegal character found in authority: "
+ + describeChar(str.charAt(index));
+ }
+ return null;
+ }
+
+ // check authority of hierarchical URL. Appropriate for
+ // HTTP-like protocol handlers
+ public static String checkAuthority(URL url) {
+ String s, u, h;
+ if (url == null) return null;
+ if ((s = checkUserInfo(u = url.getUserInfo())) != null) {
+ return s;
+ }
+ if ((s = checkHost(h = url.getHost())) != null) {
+ return s;
+ }
+ if (h == null && u == null) {
+ return checkAuth(url.getAuthority());
+ }
+ return null;
+ }
+
+ // minimal syntax checks - deeper check may be performed
+ // by the appropriate protocol handler
+ public static String checkExternalForm(URL url) {
+ String s;
+ if (url == null) return null;
+ int index = scan(s = url.getUserInfo(),
+ L_NON_PRINTABLE | L_SLASH,
+ H_NON_PRINTABLE | H_SLASH);
+ if (index >= 0) {
+ return "Illegal character found in authority: "
+ + describeChar(s.charAt(index));
+ }
+ if ((s = checkHostString(url.getHost())) != null) {
+ return s;
+ }
+ return null;
+ }
+
+ public static String checkHostString(String host) {
+ if (host == null) return null;
+ int index = scan(host,
+ L_NON_PRINTABLE | L_SLASH,
+ H_NON_PRINTABLE | H_SLASH,
+ OTHERS);
+ if (index >= 0) {
+ return "Illegal character found in host: "
+ + describeChar(host.charAt(index));
+ }
+ return null;
+ }
}
--- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.SocketPermission;
import java.net.UnknownHostException;
@@ -48,6 +49,7 @@
import java.security.Permission;
import java.util.Properties;
import sun.net.NetworkClient;
+import sun.net.util.IPAddressUtil;
import sun.net.www.MessageHeader;
import sun.net.www.MeteredStream;
import sun.net.www.URLConnection;
@@ -157,6 +159,21 @@
}
}
+ static URL checkURL(URL u) throws IllegalArgumentException {
+ if (u != null) {
+ if (u.toExternalForm().indexOf('\n') > -1) {
+ Exception mfue = new MalformedURLException("Illegal character in URL");
+ throw new IllegalArgumentException(mfue.getMessage(), mfue);
+ }
+ }
+ String s = IPAddressUtil.checkAuthority(u);
+ if (s != null) {
+ Exception mfue = new MalformedURLException(s);
+ throw new IllegalArgumentException(mfue.getMessage(), mfue);
+ }
+ return u;
+ }
+
/**
* Creates an FtpURLConnection from a URL.
*
@@ -170,7 +187,7 @@
* Same as FtpURLconnection(URL) with a per connection proxy specified
*/
FtpURLConnection(URL url, Proxy p) {
- super(url);
+ super(checkURL(url));
instProxy = p;
host = url.getHost();
port = url.getPort();
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@
import jdk.internal.access.JavaNetHttpCookieAccess;
import jdk.internal.access.SharedSecrets;
import sun.net.*;
+import sun.net.util.IPAddressUtil;
import sun.net.www.*;
import sun.net.www.http.HttpClient;
import sun.net.www.http.PosterOutputStream;
@@ -868,8 +869,13 @@
throw new MalformedURLException("Illegal character in URL");
}
}
+ String s = IPAddressUtil.checkAuthority(u);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
return u;
}
+
protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException {
super(checkURL(u));
--- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -37,6 +37,7 @@
import java.util.Map;
import java.util.List;
import java.util.Optional;
+import sun.net.util.IPAddressUtil;
import sun.net.www.http.HttpClient;
/**
@@ -69,6 +70,10 @@
throw new MalformedURLException("Illegal character in URL");
}
}
+ String s = IPAddressUtil.checkAuthority(u);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
return u;
}
@@ -289,7 +294,7 @@
* @param key the keyword by which the request is known
* (e.g., "<code>accept</code>").
* @param value the value associated with it.
- * @see #getRequestProperties(java.lang.String)
+ * @see #getRequestProperty(java.lang.String)
* @since 1.4
*/
public void addRequestProperty(String key, String value) {
--- a/src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
-
+import java.util.Objects;
/**
* This class is defined here rather than in java.nio.channels.Channels
@@ -87,10 +87,8 @@
public synchronized int read(byte[] bs, int off, int len)
throws IOException
{
- if ((off < 0) || (off > bs.length) || (len < 0) ||
- ((off + len) > bs.length) || ((off + len) < 0)) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0)
+ Objects.checkFromIndexSize(off, len, bs.length);
+ if (len == 0)
return 0;
ByteBuffer bb = ((this.bs == bs)
@@ -119,6 +117,26 @@
return 0;
}
+ public synchronized long skip(long n) throws IOException {
+ // special case where the channel is to a file
+ if (ch instanceof SeekableByteChannel && n > 0) {
+ SeekableByteChannel sbc = (SeekableByteChannel)ch;
+ try {
+ long pos = sbc.position();
+ long size = sbc.size();
+ if (pos >= size) {
+ return 0L;
+ }
+ n = Math.min(n, size - pos);
+ sbc.position(pos + n);
+ return sbc.position() - pos;
+ } catch (ClosedChannelException cce) {
+ throw new IOException(cce);
+ }
+ }
+ return super.skip(n);
+ }
+
public void close() throws IOException {
ch.close();
}
--- a/src/java.base/share/classes/sun/nio/ch/IOUtil.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/IOUtil.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -432,15 +432,8 @@
public static void load() { }
static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("net");
- System.loadLibrary("nio");
- return null;
- }
- });
-
+ jdk.internal.loader.BootLoader.loadLibrary("net");
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
initIDs();
IOV_MAX = iovMax();
--- a/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -724,12 +724,14 @@
// Update the context.
chc.handshakeExtensions.put(
SH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT);
- chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
- SSLHandshake.CERTIFICATE_STATUS);
// Since we've received a legitimate status_request in the
// ServerHello, stapling is active if it's been enabled.
chc.staplingActive = chc.sslContext.isStaplingEnabled(true);
+ if (chc.staplingActive) {
+ chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
+ SSLHandshake.CERTIFICATE_STATUS);
+ }
// No impact on session resumption.
}
@@ -1079,12 +1081,16 @@
// Update the context.
chc.handshakeExtensions.put(
SH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT);
- chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
- SSLHandshake.CERTIFICATE_STATUS);
// Since we've received a legitimate status_request in the
- // ServerHello, stapling is active if it's been enabled.
+ // ServerHello, stapling is active if it's been enabled. If it
+ // is active, make sure we add the CertificateStatus message
+ // consumer.
chc.staplingActive = chc.sslContext.isStaplingEnabled(true);
+ if (chc.staplingActive) {
+ chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
+ SSLHandshake.CERTIFICATE_STATUS);
+ }
// No impact on session resumption.
}
--- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -330,6 +330,15 @@
// clean up this consumer
chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id);
+ SSLConsumer certStatCons = chc.handshakeConsumers.remove(
+ SSLHandshake.CERTIFICATE_STATUS.id);
+ if (certStatCons != null) {
+ // Stapling was active but no certificate status message
+ // was sent. We need to run the absence handler which will
+ // check the certificate chain.
+ CertificateStatus.handshakeAbsence.absent(context, null);
+ }
+
T10CertificateRequestMessage crm =
new T10CertificateRequestMessage(chc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -647,6 +656,15 @@
// clean up this consumer
chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id);
+ SSLConsumer certStatCons = chc.handshakeConsumers.remove(
+ SSLHandshake.CERTIFICATE_STATUS.id);
+ if (certStatCons != null) {
+ // Stapling was active but no certificate status message
+ // was sent. We need to run the absence handler which will
+ // check the certificate chain.
+ CertificateStatus.handshakeAbsence.absent(context, null);
+ }
+
T12CertificateRequestMessage crm =
new T12CertificateRequestMessage(chc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
--- a/src/java.base/share/classes/sun/security/ssl/CertificateStatus.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateStatus.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -287,12 +287,16 @@
}
// Pin the received responses to the SSLSessionImpl. It will
- // be retrieved by the X509TrustManagerImpl during the certficicate
+ // be retrieved by the X509TrustManagerImpl during the certificate
// checking phase.
chc.handshakeSession.setStatusResponses(cst.encodedResponses);
// Now perform the check
T12CertificateConsumer.checkServerCerts(chc, chc.deferredCerts);
+
+ // Update the handshake consumers to remove this message, indicating
+ // that it has been processed.
+ chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_STATUS.id);
}
}
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1480,8 +1480,9 @@
checkAdditionalTrust(chain, authType, engine, false);
}
- private void checkAdditionalTrust(X509Certificate[] chain, String authType,
- Socket socket, boolean isClient) throws CertificateException {
+ private void checkAdditionalTrust(X509Certificate[] chain,
+ String authType, Socket socket,
+ boolean checkClientTrusted) throws CertificateException {
if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) {
@@ -1495,9 +1496,8 @@
String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) {
- String hostname = session.getPeerHost();
- X509TrustManagerImpl.checkIdentity(
- hostname, chain[0], identityAlg);
+ X509TrustManagerImpl.checkIdentity(session, chain,
+ identityAlg, checkClientTrusted);
}
// try the best to check the algorithm constraints
@@ -1519,12 +1519,13 @@
constraints = new SSLAlgorithmConstraints(sslSocket, true);
}
- checkAlgorithmConstraints(chain, constraints, isClient);
+ checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
}
}
- private void checkAdditionalTrust(X509Certificate[] chain, String authType,
- SSLEngine engine, boolean isClient) throws CertificateException {
+ private void checkAdditionalTrust(X509Certificate[] chain,
+ String authType, SSLEngine engine,
+ boolean checkClientTrusted) throws CertificateException {
if (engine != null) {
SSLSession session = engine.getHandshakeSession();
if (session == null) {
@@ -1535,9 +1536,8 @@
String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) {
- String hostname = session.getPeerHost();
- X509TrustManagerImpl.checkIdentity(
- hostname, chain[0], identityAlg);
+ X509TrustManagerImpl.checkIdentity(session, chain,
+ identityAlg, checkClientTrusted);
}
// try the best to check the algorithm constraints
@@ -1559,13 +1559,13 @@
constraints = new SSLAlgorithmConstraints(engine, true);
}
- checkAlgorithmConstraints(chain, constraints, isClient);
+ checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
}
}
private void checkAlgorithmConstraints(X509Certificate[] chain,
AlgorithmConstraints constraints,
- boolean isClient) throws CertificateException {
+ boolean checkClientTrusted) throws CertificateException {
try {
// Does the certificate chain end with a trusted certificate?
int checkedLength = chain.length - 1;
@@ -1584,7 +1584,7 @@
if (checkedLength >= 0) {
AlgorithmChecker checker =
new AlgorithmChecker(constraints, null,
- (isClient ? Validator.VAR_TLS_CLIENT :
+ (checkClientTrusted ? Validator.VAR_TLS_CLIENT :
Validator.VAR_TLS_SERVER));
checker.init(false);
for (int i = checkedLength; i >= 0; i--) {
--- a/src/java.base/share/classes/sun/security/ssl/ServerHelloDone.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/ServerHelloDone.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -133,6 +133,15 @@
// The consuming happens in client side only.
ClientHandshakeContext chc = (ClientHandshakeContext)context;
+ SSLConsumer certStatCons = chc.handshakeConsumers.remove(
+ SSLHandshake.CERTIFICATE_STATUS.id);
+ if (certStatCons != null) {
+ // Stapling was active but no certificate status message
+ // was sent. We need to run the absence handler which will
+ // check the certificate chain.
+ CertificateStatus.handshakeAbsence.absent(context, null);
+ }
+
// clean up this consumer
chc.handshakeConsumers.clear();
--- a/src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,6 +92,15 @@
// clean up this consumer
chc.handshakeConsumers.remove(SSLHandshake.SERVER_KEY_EXCHANGE.id);
+ SSLConsumer certStatCons = chc.handshakeConsumers.remove(
+ SSLHandshake.CERTIFICATE_STATUS.id);
+ if (certStatCons != null) {
+ // Stapling was active but no certificate status message
+ // was sent. We need to run the absence handler which will
+ // check the certificate chain.
+ CertificateStatus.handshakeAbsence.absent(context, null);
+ }
+
SSLKeyExchange ke = SSLKeyExchange.valueOf(
chc.negotiatedCipherSuite.keyExchange,
chc.negotiatedProtocol);
--- a/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -145,7 +145,7 @@
}
private Validator checkTrustedInit(X509Certificate[] chain,
- String authType, boolean isClient) {
+ String authType, boolean checkClientTrusted) {
if (chain == null || chain.length == 0) {
throw new IllegalArgumentException(
"null or zero-length certificate chain");
@@ -157,7 +157,7 @@
}
Validator v = null;
- if (isClient) {
+ if (checkClientTrusted) {
v = clientValidator;
if (v == null) {
validatorLock.lock();
@@ -192,9 +192,10 @@
return v;
}
- private void checkTrusted(X509Certificate[] chain, String authType,
- Socket socket, boolean isClient) throws CertificateException {
- Validator v = checkTrustedInit(chain, authType, isClient);
+ private void checkTrusted(X509Certificate[] chain,
+ String authType, Socket socket,
+ boolean checkClientTrusted) throws CertificateException {
+ Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
X509Certificate[] trustedChain = null;
if ((socket != null) && socket.isConnected() &&
@@ -223,28 +224,23 @@
// Grab any stapled OCSP responses for use in validation
List<byte[]> responseList = Collections.emptyList();
- if (!isClient && isExtSession) {
+ if (!checkClientTrusted && isExtSession) {
responseList =
((ExtendedSSLSession)session).getStatusResponses();
}
trustedChain = v.validate(chain, null, responseList,
- constraints, isClient ? null : authType);
-
- // check if EE certificate chains to a public root CA (as
- // pre-installed in cacerts)
- boolean chainsToPublicCA = AnchorCertificates.contains(
- trustedChain[trustedChain.length-1]);
+ constraints, checkClientTrusted ? null : authType);
// check endpoint identity
String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) {
- checkIdentity(session, trustedChain[0], identityAlg, isClient,
- getRequestedServerNames(socket), chainsToPublicCA);
+ checkIdentity(session,
+ trustedChain, identityAlg, checkClientTrusted);
}
} else {
trustedChain = v.validate(chain, null, Collections.emptyList(),
- null, isClient ? null : authType);
+ null, checkClientTrusted ? null : authType);
}
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
@@ -253,9 +249,10 @@
}
}
- private void checkTrusted(X509Certificate[] chain, String authType,
- SSLEngine engine, boolean isClient) throws CertificateException {
- Validator v = checkTrustedInit(chain, authType, isClient);
+ private void checkTrusted(X509Certificate[] chain,
+ String authType, SSLEngine engine,
+ boolean checkClientTrusted) throws CertificateException {
+ Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
X509Certificate[] trustedChain = null;
if (engine != null) {
@@ -281,28 +278,23 @@
// Grab any stapled OCSP responses for use in validation
List<byte[]> responseList = Collections.emptyList();
- if (!isClient && isExtSession) {
+ if (!checkClientTrusted && isExtSession) {
responseList =
((ExtendedSSLSession)session).getStatusResponses();
}
trustedChain = v.validate(chain, null, responseList,
- constraints, isClient ? null : authType);
-
- // check if EE certificate chains to a public root CA (as
- // pre-installed in cacerts)
- boolean chainsToPublicCA = AnchorCertificates.contains(
- trustedChain[trustedChain.length-1]);
+ constraints, checkClientTrusted ? null : authType);
// check endpoint identity
String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) {
- checkIdentity(session, trustedChain[0], identityAlg, isClient,
- getRequestedServerNames(engine), chainsToPublicCA);
+ checkIdentity(session, trustedChain,
+ identityAlg, checkClientTrusted);
}
} else {
trustedChain = v.validate(chain, null, Collections.emptyList(),
- null, isClient ? null : authType);
+ null, checkClientTrusted ? null : authType);
}
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
@@ -360,14 +352,8 @@
static List<SNIServerName> getRequestedServerNames(Socket socket) {
if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) {
-
- SSLSocket sslSocket = (SSLSocket)socket;
- SSLSession session = sslSocket.getHandshakeSession();
-
- if (session != null && (session instanceof ExtendedSSLSession)) {
- ExtendedSSLSession extSession = (ExtendedSSLSession)session;
- return extSession.getRequestedServerNames();
- }
+ return getRequestedServerNames(
+ ((SSLSocket)socket).getHandshakeSession());
}
return Collections.<SNIServerName>emptyList();
@@ -376,12 +362,16 @@
// Also used by X509KeyManagerImpl
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
if (engine != null) {
- SSLSession session = engine.getHandshakeSession();
+ return getRequestedServerNames(engine.getHandshakeSession());
+ }
- if (session != null && (session instanceof ExtendedSSLSession)) {
- ExtendedSSLSession extSession = (ExtendedSSLSession)session;
- return extSession.getRequestedServerNames();
- }
+ return Collections.<SNIServerName>emptyList();
+ }
+
+ private static List<SNIServerName> getRequestedServerNames(
+ SSLSession session) {
+ if (session != null && (session instanceof ExtendedSSLSession)) {
+ return ((ExtendedSSLSession)session).getRequestedServerNames();
}
return Collections.<SNIServerName>emptyList();
@@ -402,23 +392,28 @@
* the identity checking aginst the server_name extension if present, and
* may failove to peer host checking.
*/
- private static void checkIdentity(SSLSession session,
- X509Certificate cert,
+ static void checkIdentity(SSLSession session,
+ X509Certificate[] trustedChain,
String algorithm,
- boolean isClient,
- List<SNIServerName> sniNames,
- boolean chainsToPublicCA) throws CertificateException {
+ boolean checkClientTrusted) throws CertificateException {
+
+ // check if EE certificate chains to a public root CA (as
+ // pre-installed in cacerts)
+ boolean chainsToPublicCA = AnchorCertificates.contains(
+ trustedChain[trustedChain.length - 1]);
boolean identifiable = false;
String peerHost = session.getPeerHost();
- if (isClient) {
- String hostname = getHostNameInSNI(sniNames);
- if (hostname != null) {
+ if (!checkClientTrusted) {
+ List<SNIServerName> sniNames = getRequestedServerNames(session);
+ String sniHostName = getHostNameInSNI(sniNames);
+ if (sniHostName != null) {
try {
- checkIdentity(hostname, cert, algorithm, chainsToPublicCA);
+ checkIdentity(sniHostName,
+ trustedChain[0], algorithm, chainsToPublicCA);
identifiable = true;
} catch (CertificateException ce) {
- if (hostname.equalsIgnoreCase(peerHost)) {
+ if (sniHostName.equalsIgnoreCase(peerHost)) {
throw ce;
}
@@ -428,7 +423,8 @@
}
if (!identifiable) {
- checkIdentity(peerHost, cert, algorithm, chainsToPublicCA);
+ checkIdentity(peerHost,
+ trustedChain[0], algorithm, chainsToPublicCA);
}
}
--- a/src/java.base/share/classes/sun/security/tools/keytool/Resources_ja.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources_ja.java Mon Jul 22 11:08:27 2019 +0530
@@ -95,6 +95,8 @@
"\u81EA\u5DF1\u7F72\u540D\u578B\u8A3C\u660E\u66F8\u3092\u751F\u6210\u3057\u307E\u3059"}, //-selfcert
{"Changes.the.store.password.of.a.keystore",
"\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30B9\u30C8\u30A2\u30FB\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u5909\u66F4\u3057\u307E\u3059"}, //-storepasswd
+ {"showinfo.command.help", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u95A2\u9023\u60C5\u5831\u3092\u8868\u793A\u3057\u307E\u3059"},
+
// keytool: help: options
{"alias.name.of.the.entry.to.process",
"\u51E6\u7406\u3059\u308B\u30A8\u30F3\u30C8\u30EA\u306E\u5225\u540D"}, //-alias
@@ -140,6 +142,7 @@
"\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8868\u793A\u3057\u306A\u3044"}, //-noprompt
{"password.through.protected.mechanism",
"\u4FDD\u8B77\u30E1\u30AB\u30CB\u30BA\u30E0\u306B\u3088\u308B\u30D1\u30B9\u30EF\u30FC\u30C9"}, //-protected
+ {"tls.option.help", "TLS\u69CB\u6210\u60C5\u5831\u3092\u8868\u793A\u3057\u307E\u3059"},
// The following 2 values should span 2 lines, the first for the
// option itself, the second for its -providerArg value.
@@ -250,7 +253,6 @@
{"Keystore.password.is.too.short.must.be.at.least.6.characters",
"\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u77ED\u3059\u304E\u307E\u3059 - 6\u6587\u5B57\u4EE5\u4E0A\u306B\u3057\u3066\u304F\u3060\u3055\u3044"},
{"Unknown.Entry.Type", "\u4E0D\u660E\u306A\u30A8\u30F3\u30C8\u30EA\u30FB\u30BF\u30A4\u30D7"},
- {"Too.many.failures.Alias.not.changed", "\u969C\u5BB3\u304C\u591A\u3059\u304E\u307E\u3059\u3002\u5225\u540D\u306F\u5909\u66F4\u3055\u308C\u307E\u305B\u3093"},
{"Entry.for.alias.alias.successfully.imported.",
"\u5225\u540D{0}\u306E\u30A8\u30F3\u30C8\u30EA\u306E\u30A4\u30F3\u30DD\u30FC\u30C8\u306B\u6210\u529F\u3057\u307E\u3057\u305F\u3002"},
{"Entry.for.alias.alias.not.imported.", "\u5225\u540D{0}\u306E\u30A8\u30F3\u30C8\u30EA\u306F\u30A4\u30F3\u30DD\u30FC\u30C8\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002"},
@@ -311,10 +313,6 @@
{"Too.many.failures.Key.entry.not.cloned",
"\u969C\u5BB3\u304C\u591A\u3059\u304E\u307E\u3059\u3002\u30AD\u30FC\u30FB\u30A8\u30F3\u30C8\u30EA\u306E\u30AF\u30ED\u30FC\u30F3\u306F\u4F5C\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F"},
{"key.password.for.alias.", "<{0}>\u306E\u30AD\u30FC\u306E\u30D1\u30B9\u30EF\u30FC\u30C9"},
- {"Keystore.entry.for.id.getName.already.exists",
- "<{0}>\u306E\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30A8\u30F3\u30C8\u30EA\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059"},
- {"Creating.keystore.entry.for.id.getName.",
- "<{0}>\u306E\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30A8\u30F3\u30C8\u30EA\u3092\u4F5C\u6210\u4E2D..."},
{"No.entries.from.identity.database.added",
"\u30A2\u30A4\u30C7\u30F3\u30C6\u30A3\u30C6\u30A3\u30FB\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304B\u3089\u8FFD\u52A0\u3055\u308C\u305F\u30A8\u30F3\u30C8\u30EA\u306F\u3042\u308A\u307E\u305B\u3093"},
{"Alias.name.alias", "\u5225\u540D: {0}"},
@@ -352,7 +350,6 @@
{"Do.you.still.want.to.add.it.to.your.own.keystore.no.",
"\u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u8FFD\u52A0\u3057\u307E\u3059\u304B\u3002 [\u3044\u3044\u3048]: "},
{"Trust.this.certificate.no.", "\u3053\u306E\u8A3C\u660E\u66F8\u3092\u4FE1\u983C\u3057\u307E\u3059\u304B\u3002 [\u3044\u3044\u3048]: "},
- {"YES", "\u306F\u3044"},
{"New.prompt.", "\u65B0\u898F{0}: "},
{"Passwords.must.differ", "\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u7570\u306A\u3063\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
{"Re.enter.new.prompt.", "\u65B0\u898F{0}\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
@@ -392,7 +389,6 @@
{"Signer.d.", "\u7F72\u540D\u8005\u756A\u53F7%d:"},
{"Timestamp.", "\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7:"},
{"Signature.", "\u7F72\u540D:"},
- {"CRLs.", "CRL:"},
{"Certificate.owner.", "\u8A3C\u660E\u66F8\u306E\u6240\u6709\u8005: "},
{"Not.a.signed.jar.file", "\u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u3042\u308A\u307E\u305B\u3093"},
{"No.certificate.from.the.SSL.server",
@@ -407,13 +403,10 @@
"\u8A3C\u660E\u66F8\u5FDC\u7B54\u306B\u306F\u3001<{0}>\u306E\u516C\u958B\u30AD\u30FC\u306F\u542B\u307E\u308C\u307E\u305B\u3093"},
{"Incomplete.certificate.chain.in.reply",
"\u5FDC\u7B54\u3057\u305F\u8A3C\u660E\u66F8\u30C1\u30A7\u30FC\u30F3\u306F\u4E0D\u5B8C\u5168\u3067\u3059"},
- {"Certificate.chain.in.reply.does.not.verify.",
- "\u5FDC\u7B54\u3057\u305F\u8A3C\u660E\u66F8\u30C1\u30A7\u30FC\u30F3\u306F\u691C\u8A3C\u3055\u308C\u3066\u3044\u307E\u305B\u3093: "},
{"Top.level.certificate.in.reply.",
"\u5FDC\u7B54\u3057\u305F\u30C8\u30C3\u30D7\u30EC\u30D9\u30EB\u306E\u8A3C\u660E\u66F8:\n"},
{".is.not.trusted.", "... \u306F\u4FE1\u983C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 "},
{"Install.reply.anyway.no.", "\u5FDC\u7B54\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u307E\u3059\u304B\u3002[\u3044\u3044\u3048]: "},
- {"NO", "\u3044\u3044\u3048"},
{"Public.keys.in.reply.and.keystore.don.t.match",
"\u5FDC\u7B54\u3057\u305F\u516C\u958B\u30AD\u30FC\u3068\u30AD\u30FC\u30B9\u30C8\u30A2\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093"},
{"Certificate.reply.and.certificate.in.keystore.are.identical",
@@ -474,6 +467,8 @@
{"backup.keystore.warning", "\u5143\u306E\u30AD\u30FC\u30B9\u30C8\u30A2\"%1$s\"\u306F\"%3$s\"\u3068\u3057\u3066\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3055\u308C\u307E\u3059..."},
{"importing.keystore.status", "\u30AD\u30FC\u30B9\u30C8\u30A2%1$s\u3092%2$s\u306B\u30A4\u30F3\u30DD\u30FC\u30C8\u3057\u3066\u3044\u307E\u3059..."},
{"keyalg.option.1.missing.warning", "-keyalg\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30AD\u30FC\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0(%s)\u306F\u3001\u65E7\u5F0F\u306E\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u3067\u3001\u73FE\u5728\u306F\u63A8\u5968\u3055\u308C\u307E\u305B\u3093\u3002JDK\u306E\u5F8C\u7D9A\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u306F\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3001-keyalg\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002"},
+
+ {"showinfo.no.option", "-showinfo\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u3042\u308A\u307E\u305B\u3093\u3002\"keytool -showinfo -tls\"\u3092\u8A66\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
};
--- a/src/java.base/share/classes/sun/security/tools/keytool/Resources_zh_CN.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources_zh_CN.java Mon Jul 22 11:08:27 2019 +0530
@@ -95,6 +95,8 @@
"\u751F\u6210\u81EA\u7B7E\u540D\u8BC1\u4E66"}, //-selfcert
{"Changes.the.store.password.of.a.keystore",
"\u66F4\u6539\u5BC6\u94A5\u5E93\u7684\u5B58\u50A8\u53E3\u4EE4"}, //-storepasswd
+ {"showinfo.command.help", "\u663E\u793A\u5B89\u5168\u76F8\u5173\u4FE1\u606F"},
+
// keytool: help: options
{"alias.name.of.the.entry.to.process",
"\u8981\u5904\u7406\u7684\u6761\u76EE\u7684\u522B\u540D"}, //-alias
@@ -140,6 +142,7 @@
"\u4E0D\u63D0\u793A"}, //-noprompt
{"password.through.protected.mechanism",
"\u901A\u8FC7\u53D7\u4FDD\u62A4\u7684\u673A\u5236\u7684\u53E3\u4EE4"}, //-protected
+ {"tls.option.help", "\u663E\u793A TLS \u914D\u7F6E\u4FE1\u606F"},
// The following 2 values should span 2 lines, the first for the
// option itself, the second for its -providerArg value.
@@ -250,7 +253,6 @@
{"Keystore.password.is.too.short.must.be.at.least.6.characters",
"\u5BC6\u94A5\u5E93\u53E3\u4EE4\u592A\u77ED - \u81F3\u5C11\u5FC5\u987B\u4E3A 6 \u4E2A\u5B57\u7B26"},
{"Unknown.Entry.Type", "\u672A\u77E5\u6761\u76EE\u7C7B\u578B"},
- {"Too.many.failures.Alias.not.changed", "\u6545\u969C\u592A\u591A\u3002\u672A\u66F4\u6539\u522B\u540D"},
{"Entry.for.alias.alias.successfully.imported.",
"\u5DF2\u6210\u529F\u5BFC\u5165\u522B\u540D {0} \u7684\u6761\u76EE\u3002"},
{"Entry.for.alias.alias.not.imported.", "\u672A\u5BFC\u5165\u522B\u540D {0} \u7684\u6761\u76EE\u3002"},
@@ -311,10 +313,6 @@
{"Too.many.failures.Key.entry.not.cloned",
"\u6545\u969C\u592A\u591A\u3002\u672A\u514B\u9686\u5BC6\u94A5\u6761\u76EE"},
{"key.password.for.alias.", "<{0}> \u7684\u5BC6\u94A5\u53E3\u4EE4"},
- {"Keystore.entry.for.id.getName.already.exists",
- "<{0}> \u7684\u5BC6\u94A5\u5E93\u6761\u76EE\u5DF2\u7ECF\u5B58\u5728"},
- {"Creating.keystore.entry.for.id.getName.",
- "\u6B63\u5728\u521B\u5EFA <{0}> \u7684\u5BC6\u94A5\u5E93\u6761\u76EE..."},
{"No.entries.from.identity.database.added",
"\u672A\u4ECE\u8EAB\u4EFD\u6570\u636E\u5E93\u4E2D\u6DFB\u52A0\u4EFB\u4F55\u6761\u76EE"},
{"Alias.name.alias", "\u522B\u540D: {0}"},
@@ -352,7 +350,6 @@
{"Do.you.still.want.to.add.it.to.your.own.keystore.no.",
"\u662F\u5426\u4ECD\u8981\u5C06\u5B83\u6DFB\u52A0\u5230\u81EA\u5DF1\u7684\u5BC6\u94A5\u5E93? [\u5426]: "},
{"Trust.this.certificate.no.", "\u662F\u5426\u4FE1\u4EFB\u6B64\u8BC1\u4E66? [\u5426]: "},
- {"YES", "YES"},
{"New.prompt.", "\u65B0{0}: "},
{"Passwords.must.differ", "\u53E3\u4EE4\u4E0D\u80FD\u76F8\u540C"},
{"Re.enter.new.prompt.", "\u91CD\u65B0\u8F93\u5165\u65B0{0}: "},
@@ -392,7 +389,6 @@
{"Signer.d.", "\u7B7E\u540D\u8005 #%d:"},
{"Timestamp.", "\u65F6\u95F4\u6233:"},
{"Signature.", "\u7B7E\u540D:"},
- {"CRLs.", "CRL:"},
{"Certificate.owner.", "\u8BC1\u4E66\u6240\u6709\u8005: "},
{"Not.a.signed.jar.file", "\u4E0D\u662F\u5DF2\u7B7E\u540D\u7684 jar \u6587\u4EF6"},
{"No.certificate.from.the.SSL.server",
@@ -407,13 +403,10 @@
"\u8BC1\u4E66\u56DE\u590D\u4E2D\u4E0D\u5305\u542B <{0}> \u7684\u516C\u5171\u5BC6\u94A5"},
{"Incomplete.certificate.chain.in.reply",
"\u56DE\u590D\u4E2D\u7684\u8BC1\u4E66\u94FE\u4E0D\u5B8C\u6574"},
- {"Certificate.chain.in.reply.does.not.verify.",
- "\u56DE\u590D\u4E2D\u7684\u8BC1\u4E66\u94FE\u672A\u9A8C\u8BC1: "},
{"Top.level.certificate.in.reply.",
"\u56DE\u590D\u4E2D\u7684\u9876\u7EA7\u8BC1\u4E66:\n"},
{".is.not.trusted.", "... \u662F\u4E0D\u53EF\u4FE1\u7684\u3002"},
{"Install.reply.anyway.no.", "\u662F\u5426\u4ECD\u8981\u5B89\u88C5\u56DE\u590D? [\u5426]: "},
- {"NO", "NO"},
{"Public.keys.in.reply.and.keystore.don.t.match",
"\u56DE\u590D\u4E2D\u7684\u516C\u5171\u5BC6\u94A5\u4E0E\u5BC6\u94A5\u5E93\u4E0D\u5339\u914D"},
{"Certificate.reply.and.certificate.in.keystore.are.identical",
@@ -474,6 +467,8 @@
{"backup.keystore.warning", "\u5DF2\u5C06\u539F\u59CB\u5BC6\u94A5\u5E93 \"%1$s\" \u5907\u4EFD\u4E3A \"%3$s\"..."},
{"importing.keystore.status", "\u6B63\u5728\u5C06\u5BC6\u94A5\u5E93 %1$s \u5BFC\u5165\u5230 %2$s..."},
{"keyalg.option.1.missing.warning", "\u65E0 -keyalg \u9009\u9879\u3002\u9ED8\u8BA4\u5BC6\u94A5\u7B97\u6CD5 (%s) \u662F\u4F20\u7EDF\u7B97\u6CD5\uFF0C\u4E0D\u518D\u63A8\u8350\u3002\u5728 JDK \u7684\u540E\u7EED\u53D1\u884C\u7248\u4E2D\uFF0C\u5C06\u5220\u9664\u9ED8\u8BA4\u503C\uFF0C\u60A8\u5FC5\u987B\u6307\u5B9A -keyalg \u9009\u9879\u3002"},
+
+ {"showinfo.no.option", "-showinfo \u7F3A\u5C11\u9009\u9879\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 \"keytool -showinfo -tls\"\u3002"},
};
--- a/src/java.base/share/classes/sun/security/util/CurveDB.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/CurveDB.java Mon Jul 22 11:08:27 2019 +0530
@@ -104,21 +104,10 @@
if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
continue;
}
- if (namedCurve.getCurve().equals(params.getCurve()) == false) {
- continue;
- }
- if (namedCurve.getGenerator().equals(params.getGenerator()) ==
- false) {
- continue;
+ if (ECUtil.equals(namedCurve, params)) {
+ // everything matches our named curve, return it
+ return namedCurve;
}
- if (namedCurve.getOrder().equals(params.getOrder()) == false) {
- continue;
- }
- if (namedCurve.getCofactor() != params.getCofactor()) {
- continue;
- }
- // everything matches our named curve, return it
- return namedCurve;
}
// no match found
return null;
--- a/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java Mon Jul 22 11:08:27 2019 +0530
@@ -92,8 +92,6 @@
* add the current position to the <code>eocList</code> vector.
*/
private void parseTag() throws IOException {
- if (dataPos == dataSize)
- return;
if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) {
int numOfEncapsulatedLenBytes = 0;
Object elem = null;
@@ -332,6 +330,10 @@
// parse and set up the vectors of all the indefinite-lengths
while (dataPos < dataSize) {
+ if (dataPos + 2 > dataSize) {
+ // There should be at least one tag and one length
+ return null;
+ }
parseTag();
len = parseLength();
if (len < 0) {
--- a/src/java.base/share/classes/sun/security/util/ECUtil.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/ECUtil.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
import java.security.spec.*;
import java.util.Arrays;
-public class ECUtil {
+public final class ECUtil {
// Used by SunPKCS11 and SunJSSE.
public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
@@ -220,6 +220,21 @@
return nameSpec.getName();
}
+ public static boolean equals(ECParameterSpec spec1, ECParameterSpec spec2) {
+ if (spec1 == spec2) {
+ return true;
+ }
+
+ if (spec1 == null || spec2 == null) {
+ return false;
+ }
+ return (spec1.getCofactor() == spec2.getCofactor() &&
+ spec1.getOrder().equals(spec2.getOrder()) &&
+ spec1.getCurve().equals(spec2.getCurve()) &&
+ spec1.getGenerator().equals(spec2.getGenerator()));
+ }
+
+
// Convert the concatenation R and S in into their DER encoding
public static byte[] encodeSignature(byte[] signature) throws SignatureException {
--- a/src/java.base/share/classes/sun/security/util/HostnameChecker.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/HostnameChecker.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -260,28 +260,35 @@
* The matching is performed as per RFC 2818 rules for TLS and
* RFC 2830 rules for LDAP.<p>
*
- * The <code>name</code> parameter should represent a DNS name.
- * The <code>template</code> parameter
- * may contain the wildcard character *
+ * The <code>name</code> parameter should represent a DNS name. The
+ * <code>template</code> parameter may contain the wildcard character '*'.
*/
private boolean isMatched(String name, String template,
boolean chainsToPublicCA) {
// Normalize to Unicode, because PSL is in Unicode.
- name = IDN.toUnicode(IDN.toASCII(name));
- template = IDN.toUnicode(IDN.toASCII(template));
+ try {
+ name = IDN.toUnicode(IDN.toASCII(name));
+ template = IDN.toUnicode(IDN.toASCII(template));
+ } catch (RuntimeException re) {
+ if (SSLLogger.isOn) {
+ SSLLogger.fine("Failed to normalize to Unicode: " + re);
+ }
- if (hasIllegalWildcard(name, template, chainsToPublicCA)) {
+ return false;
+ }
+
+ if (hasIllegalWildcard(template, chainsToPublicCA)) {
return false;
}
// check the validity of the domain name template.
try {
- // Replacing wildcard character '*' with 'x' so as to check
+ // Replacing wildcard character '*' with 'z' so as to check
// the domain name template validity.
//
// Using the checking implemented in SNIHostName
- new SNIHostName(template.replace('*', 'x'));
+ new SNIHostName(template.replace('*', 'z'));
} catch (IllegalArgumentException iae) {
// It would be nice to add debug log if not matching.
return false;
@@ -299,8 +306,8 @@
/**
* Returns true if the template contains an illegal wildcard character.
*/
- private static boolean hasIllegalWildcard(String domain, String template,
- boolean chainsToPublicCA) {
+ private static boolean hasIllegalWildcard(
+ String template, boolean chainsToPublicCA) {
// not ok if it is a single wildcard character or "*."
if (template.equals("*") || template.equals("*.")) {
if (SSLLogger.isOn) {
@@ -331,25 +338,29 @@
return true;
}
- // If the wildcarded domain is a top-level domain under which names
- // can be registered, then a wildcard is not allowed.
-
if (!chainsToPublicCA) {
return false; // skip check for non-public certificates
}
- Optional<RegisteredDomain> rd = RegisteredDomain.from(domain)
- .filter(d -> d.type() == RegisteredDomain.Type.ICANN);
- if (rd.isPresent()) {
- String wDomain = afterWildcard.substring(firstDotIndex + 1);
- if (rd.get().publicSuffix().equalsIgnoreCase(wDomain)) {
- if (SSLLogger.isOn) {
- SSLLogger.fine(
- "Certificate domain name has illegal " +
- "wildcard for public suffix: " + template);
- }
- return true;
+ // If the wildcarded domain is a top-level domain under which names
+ // can be registered, then a wildcard is not allowed.
+ String wildcardedDomain = afterWildcard.substring(firstDotIndex + 1);
+ String templateDomainSuffix =
+ RegisteredDomain.from("z." + wildcardedDomain)
+ .filter(d -> d.type() == RegisteredDomain.Type.ICANN)
+ .map(RegisteredDomain::publicSuffix).orElse(null);
+ if (templateDomainSuffix == null) {
+ return false; // skip check if not known public suffix
+ }
+
+ // Is it a top-level domain?
+ if (wildcardedDomain.equalsIgnoreCase(templateDomainSuffix)) {
+ if (SSLLogger.isOn) {
+ SSLLogger.fine(
+ "Certificate domain name has illegal " +
+ "wildcard for top-level public suffix: " + template);
}
+ return true;
}
return false;
--- a/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java Mon Jul 22 11:08:27 2019 +0530
@@ -269,6 +269,8 @@
throw (CertificateException)e;
} else if (e instanceof NoSuchAlgorithmException) {
throw (NoSuchAlgorithmException)e;
+ } else if (e instanceof RuntimeException){
+ throw (RuntimeException)e;
}
}
}
--- a/src/java.base/share/classes/sun/security/util/SignatureUtil.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/SignatureUtil.java Mon Jul 22 11:08:27 2019 +0530
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.security.*;
import java.security.spec.*;
+import java.util.Locale;
import sun.security.rsa.RSAUtil;
import jdk.internal.access.SharedSecrets;
@@ -74,14 +75,9 @@
AlgorithmParameters params)
throws ProviderException {
- sigName = checkName(sigName);
+ sigName = checkName(sigName).toUpperCase(Locale.ENGLISH);
AlgorithmParameterSpec paramSpec = null;
if (params != null) {
- if (sigName.toUpperCase().indexOf("RSA") == -1) {
- throw new ProviderException
- ("Unrecognized algorithm for signature parameters " +
- sigName);
- }
// AlgorithmParameters.getAlgorithm() may returns oid if it's
// created during DER decoding. Convert to use the standard name
// before passing it to RSAUtil
@@ -93,7 +89,20 @@
throw new ProviderException(e);
}
}
- paramSpec = RSAUtil.getParamSpec(params);
+
+ if (sigName.indexOf("RSA") != -1) {
+ paramSpec = RSAUtil.getParamSpec(params);
+ } else if (sigName.indexOf("ECDSA") != -1) {
+ try {
+ paramSpec = params.getParameterSpec(ECParameterSpec.class);
+ } catch (Exception e) {
+ throw new ProviderException("Error handling EC parameters", e);
+ }
+ } else {
+ throw new ProviderException
+ ("Unrecognized algorithm for signature parameters " +
+ sigName);
+ }
}
return paramSpec;
}
@@ -103,17 +112,31 @@
public static AlgorithmParameterSpec getParamSpec(String sigName,
byte[] paramBytes)
throws ProviderException {
- sigName = checkName(sigName);
+ sigName = checkName(sigName).toUpperCase(Locale.ENGLISH);
AlgorithmParameterSpec paramSpec = null;
+
if (paramBytes != null) {
- if (sigName.toUpperCase().indexOf("RSA") == -1) {
+ if (sigName.indexOf("RSA") != -1) {
+ AlgorithmParameters params =
+ createAlgorithmParameters(sigName, paramBytes);
+ paramSpec = RSAUtil.getParamSpec(params);
+ } else if (sigName.indexOf("ECDSA") != -1) {
+ try {
+ Provider p = Signature.getInstance(sigName).getProvider();
+ paramSpec = ECUtil.getECParameterSpec(p, paramBytes);
+ } catch (Exception e) {
+ throw new ProviderException("Error handling EC parameters", e);
+ }
+ // ECUtil discards exception and returns null, so we need to check
+ // the returned value
+ if (paramSpec == null) {
+ throw new ProviderException("Error handling EC parameters");
+ }
+ } else {
throw new ProviderException
("Unrecognized algorithm for signature parameters " +
sigName);
}
- AlgorithmParameters params =
- createAlgorithmParameters(sigName, paramBytes);
- paramSpec = RSAUtil.getParamSpec(params);
}
return paramSpec;
}
--- a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -573,8 +573,12 @@
// we can then pass in the dom = -1, dow > 0 into ZoneInfo
//
// hacking, assume the >=24 is the result of ZRB optimization for
- // "last", it works for now.
- if (dom < 0 || dom >= 24) {
+ // "last", it works for now. From tzdata2019a this hacking
+ // will not work for Asia/Gaza and Asia/Hebron which follow
+ // Palestine DST rules.
+ if (dom < 0 || dom >= 24 &&
+ !(zoneId.equals("Asia/Gaza") ||
+ zoneId.equals("Asia/Hebron"))) {
params[1] = -1;
params[2] = toCalendarDOW[dow];
} else {
--- a/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -370,7 +370,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
@@ -691,6 +691,9 @@
{"Asia/Pontianak", WIT},
{"Asia/Pyongyang", KST},
{"Asia/Qatar", ARAST},
+ {"Asia/Qostanay", new String[] {"Kostanay Standard Time", "QOST",
+ "Kostanay Summer Time", "QOSST",
+ "Kostanay Time", "QOST"}},
{"Asia/Qyzylorda", new String[] {"Qyzylorda Time", "QYZT",
"Qyzylorda Summer Time", "QYZST",
"Qyzylorda Time", "QYZT"}},
--- a/src/java.base/share/man/java.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/share/man/java.1 Mon Jul 22 11:08:27 2019 +0530
@@ -109,7 +109,7 @@
.SH DESCRIPTION
.PP
The \f[CB]java\f[R] command starts a Java application.
-It does this by starting the Java Runtime Environment (JRE), loading the
+It does this by starting the Java Virtual Machine (JVM), loading the
specified class, and calling that class\[aq]s \f[CB]main()\f[R] method.
The method must be declared \f[CB]public\f[R] and \f[CB]static\f[R], it must
not return any value, and it must accept a \f[CB]String\f[R] array as a
@@ -566,7 +566,7 @@
.RS
.RE
.TP
-.B \f[CB]\-disableassertions\f[R][\f[CB]:\f[R][\f[I]packagename\f[R]]...|\f[CB]:\f[R]\f[I]classname\f[R]] or \f[CB]\-da\\[\f[R]:\f[CB]\\[*packagename*\\]...|\f[R]:`\f[I]classname\f[R]]
+.B \f[CB]\-disableassertions\f[R][\f[CB]:\f[R][\f[I]packagename\f[R]]...|\f[CB]:\f[R]\f[I]classname\f[R]] or \f[CB]\-da\f[R][\f[CB]:\f[R][\f[I]packagename\f[R]]...|\f[CB]:\f[R]\f[I]classname\f[R]]
Disables assertions.
By default, assertions are disabled in all packages and classes.
With no arguments, \f[CB]\-disableassertions\f[R] (\f[CB]\-da\f[R]) disables
@@ -606,7 +606,7 @@
.RS
.RE
.TP
-.B \f[CB]\-enableassertions\f[R][\f[CB]:\f[R][\f[I]packagename\f[R]]...|\f[CB]:\f[R]\f[I]classname\f[R]] or \f[CB]\-ea\\[\f[R]:\f[CB]\\[*packagename*\\]...|\f[R]:`\f[I]classname\f[R]]
+.B \f[CB]\-enableassertions\f[R][\f[CB]:\f[R][\f[I]packagename\f[R]]...|\f[CB]:\f[R]\f[I]classname\f[R]] or \f[CB]\-ea\f[R][\f[CB]:\f[R][\f[I]packagename\f[R]]...|\f[CB]:\f[R]\f[I]classname\f[R]]
Enables assertions.
By default, assertions are disabled in all packages and classes.
With no arguments, \f[CB]\-enableassertions\f[R] (\f[CB]\-ea\f[R]) enables
@@ -659,6 +659,7 @@
.TP
.B \f[CB]\-javaagent:\f[R]\f[I]jarpath\f[R][\f[CB]=\f[R]\f[I]options\f[R]]
Loads the specified Java programming language agent.
+See \f[CB]java.lang.instrument\f[R].
.RS
.RE
.TP
@@ -718,12 +719,12 @@
.RE
.TP
.B \f[CB]\-\-version\f[R]
-Prints product version to the error stream and exits.
+Prints product version to the output stream and exits.
.RS
.RE
.TP
.B \f[CB]\-version\f[R]
-Prints product version to the output stream and exits.
+Prints product version to the error stream and exits.
.RS
.RE
.TP
@@ -747,7 +748,7 @@
files after shell expansion, but before argument processing.
Contents in the argument files are expanded because otherwise, they
would be specified on the command line until the
-\f[CB]\-Xdisable\-\@files\f[R] option was encountered.
+\f[CB]\-\-disable\-\@files\f[R] option was encountered.
.RS
.PP
The argument files can also contain the main class name and all options.
@@ -856,7 +857,7 @@
.TP
.B \f[CB]\-Xmn\f[R] \f[I]size\f[R]
Sets the initial and maximum size (in bytes) of the heap for the young
-generation (nursery).
+generation (nursery) in the generational collectors.
Append the letter \f[CB]k\f[R] or \f[CB]K\f[R] to indicate kilobytes,
\f[CB]m\f[R] or \f[CB]M\f[R] to indicate megabytes, or \f[CB]g\f[R] or
\f[CB]G\f[R] to indicate gigabytes.
@@ -866,8 +867,10 @@
garbage collections are performed.
If the size is too large, then only full garbage collections are
performed, which can take a long time to complete.
-It is recommended that you keep the size for the young generation
-greater than 25% and less than 50% of the overall heap size.
+It is recommended that you do not set the size for the young generation
+for the G1 collector, and keep the size for the young generation greater
+than 25% and less than 50% of the overall heap size for other
+collectors.
The following examples show how to set the initial and maximum size of
young generation to 256 MB using various units:
.RS
@@ -887,7 +890,7 @@
.RE
.TP
.B \f[CB]\-Xms\f[R] \f[I]size\f[R]
-Sets the initial size (in bytes) of the heap.
+Sets the minimum and initial size (in bytes) of the heap.
This value must be a multiple of 1024 and greater than 1 MB.
Append the letter \f[CB]k\f[R] or \f[CB]K\f[R] to indicate kilobytes,
\f[CB]m\f[R] or \f[CB]M\f[R] to indicate megabytes, \f[CB]g\f[R] or \f[CB]G\f[R]
@@ -904,16 +907,18 @@
\f[R]
.fi
.PP
-If you don\[aq]t set this option, then the initial size is set as the
-sum of the sizes allocated for the old generation and the young
-generation.
+Instead of the \f[CB]\-Xms\f[R] option to set both the minimum and initial
+size of the heap, you can use \f[CB]\-XX:MinHeapSize\f[R] to set the
+minimum size and \f[CB]\-XX:InitialHeapSize\f[R] to set the initial size.
+.PP
+If you don\[aq]t set this option, the initial size is set as the sum of
+the sizes allocated for the old generation and the young generation.
The initial size of the heap for the young generation can be set using
the \f[CB]\-Xmn\f[R] option or the \f[CB]\-XX:NewSize\f[R] option.
.RE
.TP
.B \f[CB]\-Xmx\f[R] \f[I]size\f[R]
-Specifies the maximum size (in bytes) of the memory allocation pool in
-bytes.
+Specifies the maximum size (in bytes) of the heap.
This value must be a multiple of 1024 and greater than 2 MB.
Append the letter \f[CB]k\f[R] or \f[CB]K\f[R] to indicate kilobytes,
\f[CB]m\f[R] or \f[CB]M\f[R] to indicate megabytes, or \f[CB]g\f[R] or
@@ -1205,13 +1210,6 @@
.RS
.RE
.TP
-.B \f[CB]\-\-disable\-\@files\f[R]
-Can be used anywhere on the command line, including in an argument file,
-to prevent further \f[CB]\@\f[R]\f[I]filename\f[R] expansion.
-This option stops expanding \f[CB]\@\f[R]\-argfiles after the option.
-.RS
-.RE
-.TP
.B \f[CB]\-\-source\f[R] \f[I]version\f[R]
Sets the version of the source in source\-file mode.
.RS
@@ -1392,32 +1390,13 @@
.RS
.RE
.TP
-.B \f[CB]\-XX:+FlightRecorder\f[R]
-Enables the use of Java Flight Recorder (JFR) during the runtime of the
-application.
-.RS
-.RS
-.PP
-\f[B]Note:\f[R] The \f[CB]\-XX:+FlightRecorder\f[R] option is no longer
-required to use JFR.
-This was a change made in JDK 8u40.
-.RE
-.RE
-.TP
-.B \f[CB]\-XX:FlightRecorderOptions=\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R]
+.B \f[CB]\-XX:FlightRecorderOptions=\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] (or)\f[CB]\-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R]
Sets the parameters that control the behavior of JFR.
.RS
.PP
The following list contains the available JFR
\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] entries:
.TP
-.B \f[CB]allow_threadbuffers_to_disk=\f[R]{\f[CB]true\f[R]|\f[CB]false\f[R]}
-Specifies whether thread buffers are written directly to disk if the
-buffer thread is blocked.
-By default, this parameter is disabled.
-.RS
-.RE
-.TP
.B \f[CB]globalbuffersize=\f[R]\f[I]size\f[R]
Specifies the total amount of primary memory used for data retention.
The default value is based on the value specified for
@@ -1492,7 +1471,8 @@
.TP
.B \f[CB]threadbuffersize=\f[R]\f[I]size\f[R]
Specifies the per\-thread local buffer size (in bytes).
-By default, the local buffer size is set to 8 kilobytes.
+By default, the local buffer size is set to 8 kilobytes, with a minimum
+value of 4 kilobytes.
Overriding this parameter could reduce performance and is not
recommended.
.RS
@@ -2978,19 +2958,17 @@
This sets various parameters to be optimal for long\-running jobs with
intensive memory allocation, based on the configuration of the computer
(RAM and CPU).
-By default, the option is disabled and the heap isn't optimized.
+By default, the option is disabled and the heap sizes are configured
+less aggressively.
.RS
.RE
.TP
.B \f[CB]\-XX:+AlwaysPreTouch\f[R]
-Enables touching of every page on the Java heap during JVM
-initialization.
-This gets all pages into memory before entering the \f[CB]main()\f[R]
-method.
-The option can be used in testing to simulate a long\-running system
-with all virtual memory mapped to physical memory.
-By default, this option is disabled and all pages are committed as JVM
-heap space fills.
+Requests the VM to touch every page on the Java heap after requesting it
+from the operating system and before handing memory out to the
+application.
+By default, this option is disabled and all pages are committed as the
+application uses the heap space.
.RS
.RE
.TP
@@ -3026,12 +3004,10 @@
.RS
.PP
The following example shows how to set the factor to 20%:
-.IP
-.nf
-\f[CB]
->\ \ \ `\-XX:CMSInitiatingOccupancyFraction=20`
-\f[R]
-.fi
+.RS
+.PP
+\f[CB]\-XX:CMSInitiatingOccupancyFraction=20\f[R]
+.RE
.RE
.TP
.B \f[CB]\-XX:CMSIncrementalDutySafetyFactor=\f[R]\f[I]percent\f[R]
@@ -3095,11 +3071,14 @@
.RS
.RE
.TP
-.B \f[CB]\-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses\f[R]
-Enables invoking of concurrent GC by using the \f[CB]System.gc()\f[R]
-request and unloading of classes during the concurrent GC cycle.
-This option is disabled by default and can be enabled only with the
-deprecated \f[CB]\-XX:+UseConcMarkSweepGC\f[R] option.
+.B \f[CB]\-XX:G1AdaptiveIHOPNumInitialSamples=\f[R]\f[I]number\f[R]
+When \f[CB]\-XX:UseAdaptiveIHOP\f[R] is enabled, this option sets the
+number of completed marking cycles used to gather samples until G1
+adaptively determines the optimum value of
+\f[CB]\-XX:InitiatingHeapOccupancyPercent\f[R].
+Before, G1 uses the value of
+\f[CB]\-XX:InitiatingHeapOccupancyPercent\f[R] directly for this purpose.
+The default value is 3.
.RS
.RE
.TP
@@ -3107,10 +3086,8 @@
Sets the size of the regions into which the Java heap is subdivided when
using the garbage\-first (G1) collector.
The value is a power of 2 and can range from 1 MB to 32 MB.
-The goal is to have around 2048 regions based on the minimum Java heap
-size.
The default region size is determined ergonomically based on the heap
-size.
+size with a goal of approximately 2048 regions.
.RS
.PP
The following example sets the size of the subdivisions to 16 MB:
@@ -3137,8 +3114,6 @@
.PP
This is an experimental flag.
This setting replaces the \f[CB]\-XX:DefaultMaxNewGenPercent\f[R] setting.
-.PP
-This setting isn\[aq]t available in Java HotSpot VM build 23 or earlier.
.RE
.TP
.B \f[CB]\-XX:G1MixedGCCountTarget=\f[R]\f[I]number\f[R]
@@ -3148,8 +3123,6 @@
The default is 8 mixed garbage collections.
The goal for mixed collections is to be within this target number.
.RS
-.PP
-This setting isn\[aq]t available in Java HotSpot VM build 23 or earlier.
.RE
.TP
.B \f[CB]\-XX:G1MixedGCLiveThresholdPercent=\f[R]\f[I]percent\f[R]
@@ -3161,8 +3134,6 @@
This is an experimental flag.
This setting replaces the
\f[CB]\-XX:G1OldCSetRegionLiveThresholdPercent\f[R] setting.
-.PP
-This setting isn\[aq]t available in Java HotSpot VM build 23 or earlier.
.RE
.TP
.B \f[CB]\-XX:G1NewSizePercent=\f[R]\f[I]percent\f[R]
@@ -3173,8 +3144,6 @@
.PP
This is an experimental flag.
This setting replaces the \f[CB]\-XX:DefaultMinNewGenPercent\f[R] setting.
-.PP
-This setting isn\[aq]t available in Java HotSpot VM build 23 or earlier.
.RE
.TP
.B \f[CB]\-XX:G1OldCSetRegionThresholdPercent=\f[R]\f[I]percent\f[R]
@@ -3182,8 +3151,6 @@
a mixed garbage collection cycle.
The default is 10 percent of the Java heap.
.RS
-.PP
-This setting isn\[aq]t available in Java HotSpot VM build 23 or earlier.
.RE
.TP
.B \f[CB]\-XX:G1ReservePercent=\f[R]\f[I]percent\f[R]
@@ -3202,10 +3169,20 @@
.RE
.RE
.TP
-.B \f[CB]\-XX:InitialHeapOccupancyPercent=\f[R]\f[I]percent\f[R]
-Sets the Java heap occupancy threshold that triggers a marking cycle.
-The default occupancy is 45 percent of the entire Java heap.
-.RS
+.B \f[CB]\-XX:+G1UseAdaptiveIHOP\f[R]
+Controls adaptive calculation of the old generation occupancy to start
+background work preparing for an old generation collection.
+If enabled, G1 uses \f[CB]\-XX:InitiatingHeapOccupancyPercent\f[R] for the
+first few times as specified by the value of
+\f[CB]\-XX:G1AdaptiveIHOPNumInitialSamples\f[R], and after that adaptively
+calculates a new optimum value for the initiating occupancy
+automatically.
+Otherwise, the old generation collection process always starts at the
+old generation occupancy determined by
+\f[CB]\-XX:InitiatingHeapOccupancyPercent\f[R].
+.RS
+.PP
+The default is enabled.
.RE
.TP
.B \f[CB]\-XX:InitialHeapSize=\f[R]\f[I]size\f[R]
@@ -3276,15 +3253,18 @@
.RE
.TP
.B \f[CB]\-XX:InitiatingHeapOccupancyPercent=\f[R]\f[I]percent\f[R]
-Sets the percentage of the heap occupancy (0 to 100) at which to start a
-concurrent GC cycle.
-It\[aq]s used by garbage collectors that trigger a concurrent GC cycle
-based on the occupancy of the entire heap, not just one of the
-generations (for example, the G1 garbage collector).
+Sets the percentage of the old generation occupancy (0 to 100) at which
+to start the first few concurrent marking cycles for the G1 garbage
+collector.
.RS
.PP
By default, the initiating value is set to 45%.
-A value of 0 implies nonstop GC cycles.
+A value of 0 implies nonstop concurrent GC cycles from the beginning
+until G1 adaptively sets this value.
+.PP
+See also the \f[CB]\-XX:G1UseAdaptiveIHOP\f[R] and
+\f[CB]\-XX:G1AdaptiveIHOPNumInitialSamples\f[R] options.
+.PP
The following example shows how to set the initiating heap occupancy to
75%:
.RS
@@ -3298,7 +3278,9 @@
This is a soft goal, and the JVM will make its best effort to achieve
it.
The specified value doesn\[aq]t adapt to your heap size.
-By default, there\[aq]s no maximum pause time value.
+By default, for G1 the maximum pause time target is 200 milliseconds.
+The other generational collectors do not use a pause time goal by
+default.
.RS
.PP
The following example shows how to set the maximum target pause time to
@@ -3332,13 +3314,6 @@
\f[R]
.fi
.PP
-On Oracle Solaris 7 and Oracle Solaris 8 SPARC platforms, the upper
-limit for this value is approximately 4,000 MB minus overhead amounts.
-On Oracle Solaris 2.6 and x86 platforms, the upper limit is
-approximately 2,000 MB minus overhead amounts.
-On Linux platforms, the upper limit is approximately 2,000 MB minus
-overhead amounts.
-.PP
The \f[CB]\-XX:MaxHeapSize\f[R] option is equivalent to \f[CB]\-Xmx\f[R].
.RE
.TP
@@ -3450,6 +3425,32 @@
embedded applications.
.RE
.TP
+.B \f[CB]\-XX:MinHeapSize=\f[R]\f[I]size\f[R]
+Sets the minimum size (in bytes) of the memory allocation pool.
+This value must be either 0, or a multiple of 1024 and greater than 1
+MB.
+Append the letter \f[CB]k\f[R] or \f[CB]K\f[R] to indicate kilobytes,
+\f[CB]m\f[R] or \f[CB]M\f[R] to indicate megabytes, or \f[CB]g\f[R] or
+\f[CB]G\f[R] to indicate gigabytes.
+The default value is selected at run time based on the system
+configuration.
+.RS
+.PP
+The following examples show how to set the mimimum size of allocated
+memory to 6 MB using various units:
+.IP
+.nf
+\f[CB]
+\-XX:MinHeapSize=6291456
+\-XX:MinHeapSize=6144k
+\-XX:MinHeapSize=6m
+\f[R]
+.fi
+.PP
+If you set this option to 0, then the minimum size is set to the same
+value as the initial size.
+.RE
+.TP
.B \f[CB]\-XX:NewRatio=\f[R]\f[I]ratio\f[R]
Sets the ratio between young and old generation sizes.
By default, this option is set to 2.
@@ -3493,23 +3494,13 @@
.RE
.TP
.B \f[CB]\-XX:ParallelGCThreads=\f[R]\f[I]threads\f[R]
-Sets the value of the stop\-the\-world (STW) worker threads.
-This option sets the value of \f[I]threads\f[R] to the number of logical
-processors.
-The value of \f[I]threads\f[R] is the same as the number of logical
-processors up to a value of 8.
-.RS
-.PP
-If there are more than 8 logical processors, then this option sets the
-value of \f[I]threads\f[R] to approximately 5/8 of the logical
-processors.
-This works in most cases except for larger SPARC systems where the value
-of \f[I]threads\f[R] can be approximately 5/16 of the logical processors.
-.PP
-The default value depends on the number of CPUs available to the JVM.
-.PP
-For example, to set the number of threads for parallel GC to 2, specify
-the following option:
+Sets the number of the stop\-the\-world (STW) worker threads.
+The default value depends on the number of CPUs available to the JVM and
+the garbage collector selected.
+.RS
+.PP
+For example, to set the number of threads for G1 GC to 2, specify the
+following option:
.RS
.PP
\f[CB]\-XX:ParallelGCThreads=2\f[R]
@@ -3749,6 +3740,22 @@
To disable the use of TLABs, specify the option \f[CB]\-XX:\-UseTLAB\f[R].
.RS
.RE
+.TP
+.B \f[CB]\-XX:+UseZGC\f[R]
+Enables the use of the Z garbage collector.
+This garbage collector is best for providing lowest latency with large
+Java heaps at some throughput cost.
+This is an experimental garbage collector, you need to specify
+\f[CB]\-XX:+UnlockExperimentalVMOptions\f[R] before \f[CB]\-XX:+UseZGC\f[R]
+on the command line.
+.RS
+.PP
+Example:
+.RS
+.PP
+\f[CB]\-XX:+UnlockExperimentalVMOptions\ \-XX:+UseZGC\f[R]
+.RE
+.RE
.SH DEPRECATED JAVA OPTIONS
.PP
These \f[CB]java\f[R] options are deprecated and might be removed in a
@@ -3788,6 +3795,13 @@
.RS
.RE
.TP
+.B \f[CB]\-XX:+FlightRecorder\f[R]
+Enables the use of Java Flight Recorder (JFR) during the runtime of the
+application.
+Since JDK 8u40 this option has not been required to use JFR.
+.RS
+.RE
+.TP
.B \f[CB]\-XX:+TraceClassLoading\f[R]
Enables tracing of classes as they are loaded.
By default, this option is disabled and classes aren\[aq]t traced.
@@ -3926,8 +3940,8 @@
argument list just as they would be specified on the command line.
.PP
The \f[CB]java\f[R] launcher expands the argument file contents until it
-encounters the \f[CB]\-Xdisable\-\@files\f[R] option.
-You can use the \f[CB]\-Xdisable\-\@files\f[R] option anywhere on the
+encounters the \f[CB]\-\-disable\-\@files\f[R] option.
+You can use the \f[CB]\-\-disable\-\@files\f[R] option anywhere on the
command line, including in an argument file, to stop \f[CB]\@\f[R]
argument files expansion.
.PP
@@ -5603,7 +5617,7 @@
response times for your application:
.RS
.PP
-\f[CB]java\ \-XX:+UseG1GC\ \-Xms26g\ Xmx26g\ \-XX:MaxGCPauseMillis=500\f[R]
+\f[CB]java\ \-XX:+UseG1GC\ \-XX:MaxGCPauseMillis=100\f[R]
.RE
.SS Keeping the Java Heap Small and Reducing the Dynamic Footprint of
Embedded Applications
--- a/src/java.base/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,9 +25,6 @@
package sun.nio.fs;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
/**
* Solaris specific system calls.
*/
@@ -52,11 +49,7 @@
private static native void init();
static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
init();
}
}
--- a/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.*;
import java.io.IOException;
import jdk.internal.misc.Unsafe;
@@ -817,11 +815,7 @@
throws UnixException;
static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
init();
}
}
--- a/src/java.base/unix/classes/sun/net/PortConfig.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/unix/classes/sun/net/PortConfig.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,7 @@
package sun.net;
-import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
/**
* Determines the ephemeral port range in use on this system.
@@ -41,35 +41,29 @@
private PortConfig() {}
static {
- AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- String os = System.getProperty("os.name");
- if (os.startsWith("Linux")) {
- defaultLower = 32768;
- defaultUpper = 61000;
- } else if (os.startsWith("SunOS")) {
- defaultLower = 32768;
- defaultUpper = 65535;
- } else if (os.contains("OS X")) {
- defaultLower = 49152;
- defaultUpper = 65535;
- } else if (os.startsWith("AIX")) {
- // The ephemeral port is OS version dependent on AIX:
- // http://publib.boulder.ibm.com/infocenter/aix/v7r1/topic/com.ibm.aix.rsct315.admin/bl503_ephport.htm
- // However, on AIX 5.3 / 6.1 / 7.1 we always see the
- // settings below by using:
- // /usr/sbin/no -a | fgrep ephemeral
- defaultLower = 32768;
- defaultUpper = 65535;
- } else {
- throw new InternalError(
- "sun.net.PortConfig: unknown OS");
- }
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
+ String os = GetPropertyAction.privilegedGetProperty("os.name");
+ if (os.startsWith("Linux")) {
+ defaultLower = 32768;
+ defaultUpper = 61000;
+ } else if (os.startsWith("SunOS")) {
+ defaultLower = 32768;
+ defaultUpper = 65535;
+ } else if (os.contains("OS X")) {
+ defaultLower = 49152;
+ defaultUpper = 65535;
+ } else if (os.startsWith("AIX")) {
+ // The ephemeral port is OS version dependent on AIX:
+ // http://publib.boulder.ibm.com/infocenter/aix/v7r1/topic/com.ibm.aix.rsct315.admin/bl503_ephport.htm
+ // However, on AIX 5.3 / 6.1 / 7.1 we always see the
+ // settings below by using:
+ // /usr/sbin/no -a | fgrep ephemeral
+ defaultLower = 32768;
+ defaultUpper = 65535;
+ } else {
+ throw new InternalError(
+ "sun.net.PortConfig: unknown OS");
+ }
int v = getLower0();
if (v == -1) {
--- a/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -259,13 +259,7 @@
static native String fallbackDomain0();
static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
}
}
--- a/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,6 @@
import java.nio.file.LinkOption;
import java.nio.file.LinkPermission;
import java.nio.file.StandardCopyOption;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@@ -628,12 +626,7 @@
throws UnixException;
static {
- AccessController.doPrivileged(new PrivilegedAction<>() {
- @Override
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
}
}
--- a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Mon Jul 22 11:08:27 2019 +0530
@@ -25,9 +25,6 @@
package sun.nio.fs;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
/**
* Unix system and library calls.
*/
@@ -630,11 +627,7 @@
private static native int init();
static {
- AccessController.doPrivileged(new PrivilegedAction<>() {
- public Void run() {
- System.loadLibrary("nio");
- return null;
- }});
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
capabilities = init();
}
}
--- a/src/java.base/unix/native/libnet/NetworkInterface.c Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/unix/native/libnet/NetworkInterface.c Mon Jul 22 11:08:27 2019 +0530
@@ -320,33 +320,9 @@
return obj;
}
-/*
- * Class: java_net_NetworkInterface
- * Method: getByInetAddress0
- * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
- */
-JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
- (JNIEnv *env, jclass cls, jobject iaObj)
-{
- netif *ifs, *curr;
- jobject obj = NULL;
- jboolean match = JNI_FALSE;
- int family = getInetAddress_family(env, iaObj);
- JNU_CHECK_EXCEPTION_RETURN(env, NULL);
-
- if (family == java_net_InetAddress_IPv4) {
- family = AF_INET;
- } else if (family == java_net_InetAddress_IPv6) {
- family = AF_INET6;
- } else {
- return NULL; // Invalid family
- }
- ifs = enumInterfaces(env);
- if (ifs == NULL) {
- return NULL;
- }
-
- curr = ifs;
+// Return the interface in ifs that iaObj is bound to, if any - otherwise NULL
+static netif* find_bound_interface(JNIEnv *env, netif* ifs, jobject iaObj, int family) {
+ netif* curr = ifs;
while (curr != NULL) {
netaddr *addrP = curr->addr;
@@ -359,11 +335,10 @@
((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr);
int address2 = getInetAddress_addr(env, iaObj);
if ((*env)->ExceptionCheck(env)) {
- goto cleanup;
+ return NULL;
}
if (address1 == address2) {
- match = JNI_TRUE;
- break;
+ return curr;
}
} else if (family == AF_INET6) {
jbyte *bytes = (jbyte *)&(
@@ -383,30 +358,117 @@
i++;
}
if (i >= 16) {
- match = JNI_TRUE;
- break;
+ return curr;
}
}
}
- if (match) {
- break;
- }
addrP = addrP->next;
}
-
- if (match) {
- break;
- }
curr = curr->next;
}
+ return NULL;
+}
+
+/*
+ * Class: java_net_NetworkInterface
+ * Method: boundInetAddress0
+ * Signature: (Ljava/net/InetAddress;)boundInetAddress;
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0
+ (JNIEnv *env, jclass cls, jobject iaObj)
+{
+ netif *ifs = NULL;
+ jboolean bound = JNI_FALSE;
+ int sock;
+
+ int family = getInetAddress_family(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+ if (family == java_net_InetAddress_IPv4) {
+ family = AF_INET;
+ } else if (family == java_net_InetAddress_IPv6) {
+ family = AF_INET6;
+ } else {
+ return JNI_FALSE; // Invalid family
+ }
+
+ if (family == AF_INET) {
+ sock = openSocket(env, AF_INET);
+ if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+ return JNI_FALSE;
+ }
+
+ // enumerate IPv4 addresses
+ if (sock >= 0) {
+ ifs = enumIPv4Interfaces(env, sock, ifs);
+ close(sock);
+
+ if ((*env)->ExceptionOccurred(env)) {
+ goto cleanup;
+ }
+ }
+ if (find_bound_interface(env, ifs, iaObj, family) != NULL)
+ bound = JNI_TRUE;
+ } else if (ipv6_available()) {
+ // If IPv6 is available then enumerate IPv6 addresses.
+ // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
+ // so we have to call ipv6_available()
+ sock = openSocket(env, AF_INET6);
+ if (sock < 0) {
+ return JNI_FALSE;
+ }
+
+ ifs = enumIPv6Interfaces(env, sock, ifs);
+ close(sock);
+
+ if ((*env)->ExceptionOccurred(env)) {
+ goto cleanup;
+ }
+
+ if (find_bound_interface(env, ifs, iaObj, family) != NULL)
+ bound = JNI_TRUE;
+ }
+
+cleanup:
+ freeif(ifs);
+
+ return bound;
+}
+
+/*
+ * Class: java_net_NetworkInterface
+ * Method: getByInetAddress0
+ * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
+ (JNIEnv *env, jclass cls, jobject iaObj)
+{
+ netif *ifs, *curr;
+ jobject obj = NULL;
+ int family = getInetAddress_family(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+
+ if (family == java_net_InetAddress_IPv4) {
+ family = AF_INET;
+ } else if (family == java_net_InetAddress_IPv6) {
+ family = AF_INET6;
+ } else {
+ return NULL; // Invalid family
+ }
+ ifs = enumInterfaces(env);
+ if (ifs == NULL) {
+ return NULL;
+ }
+
+ curr = find_bound_interface(env, ifs, iaObj, family);
+
// if found create a NetworkInterface
- if (match) {
+ if (curr != NULL) {
obj = createNetworkInterface(env, curr);
}
-cleanup:
// release the interface list
freeif(ifs);
--- a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -160,13 +160,7 @@
static native int notifyAddrChange0();
static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("net");
- return null;
- }
- });
+ jdk.internal.loader.BootLoader.loadLibrary("net");
init0();
// start the address listener thread
--- a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,7 @@
path = "\\\\" + host + path;
File f = new File(path);
if (f.exists()) {
- return createFileURLConnection(url, f);
+ return new UNCFileURLConnection(url, f, path);
}
/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/windows/classes/sun/net/www/protocol/file/UNCFileURLConnection.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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.net.www.protocol.file;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.net.URL;
+import java.security.Permission;
+
+final class UNCFileURLConnection extends FileURLConnection {
+
+ private final String effectivePath;
+ private volatile Permission permission;
+
+ UNCFileURLConnection(URL u, File file, String effectivePath) {
+ super(u, file);
+ this.effectivePath = effectivePath;
+ }
+
+ @Override
+ public Permission getPermission() {
+ Permission perm = permission;
+ if (perm == null) {
+ permission = perm = new FilePermission(effectivePath, "read");
+ }
+ return perm;
+ }
+}
+
--- a/src/java.base/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,8 +27,6 @@
import java.nio.file.*;
import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
/**
* File type detector that does lookup of file extension using Windows Registry.
@@ -70,13 +68,8 @@
private static native String queryStringValue(long subKey, long name);
static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- @Override
- public Void run() {
- // nio.dll has dependency on net.dll
- System.loadLibrary("net");
- System.loadLibrary("nio");
- return null;
- }});
+ // nio.dll has dependency on net.dll
+ jdk.internal.loader.BootLoader.loadLibrary("net");
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
}
}
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Mon Jul 22 11:08:27 2019 +0530
@@ -25,8 +25,6 @@
package sun.nio.fs;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsConstants.*;
@@ -1153,13 +1151,9 @@
private static native void initIDs();
static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- // nio.dll has dependency on net.dll
- System.loadLibrary("net");
- System.loadLibrary("nio");
- return null;
- }});
+ // nio.dll has dependency on net.dll
+ jdk.internal.loader.BootLoader.loadLibrary("net");
+ jdk.internal.loader.BootLoader.loadLibrary("nio");
initIDs();
}
--- a/src/java.base/windows/native/libnet/NetworkInterface.c Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/windows/native/libnet/NetworkInterface.c Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,7 @@
#include "net_util.h"
#include "NetworkInterface.h"
+#include "java_net_InetAddress.h"
#include "java_net_NetworkInterface.h"
/*
@@ -347,7 +348,7 @@
/*
* Free the interface table and return the interface list
*/
- if (tableP) {
+ if (tableP != NULL) {
free(tableP);
}
*netifPP = netifP;
@@ -355,24 +356,13 @@
}
/*
- * Enumerate the IP addresses on an interface using the IP helper library
- * routine GetIfAddrTable and matching based on the index name. There are
- * more efficient routines but we use GetIfAddrTable because it's avaliable
- * on 98 and NT.
- *
- * Returns the count of addresses, or -1 if error. If no error occurs then
- * netaddrPP will return a list of netaddr structures with the IP addresses.
+ * Enumerate all addresses using the IP helper library
*/
-int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP)
+int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP)
{
MIB_IPADDRTABLE *tableP;
ULONG size;
DWORD ret;
- DWORD i;
- netaddr *netaddrP;
- int count = 0;
- unsigned long mask;
-
/*
* Use GetIpAddrTable to enumerate the IP Addresses
*/
@@ -396,7 +386,7 @@
ret = GetIpAddrTable(tableP, &size, FALSE);
}
if (ret != NO_ERROR) {
- if (tableP) {
+ if (tableP != NULL) {
free(tableP);
}
JNU_ThrowByName(env, "java/lang/Error",
@@ -405,16 +395,35 @@
// GetIpAddrTable in pure IPv6 environment
return -2;
}
+ *tablePP = tableP;
+ return 0;
+}
+
+/*
+ * Enumerate the IP addresses on an interface, given an IP address table
+ * and matching based on index.
+ *
+ * Returns the count of addresses, or -1 if error. If no error occurs then
+ * netaddrPP will return a list of netaddr structures with the IP addresses.
+ */
+int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrPP, MIB_IPADDRTABLE *tableP)
+{
+ DWORD i;
+ netaddr *netaddrP;
+ int count = 0;
+ unsigned long mask;
/*
* Iterate through the table to find the addresses with the
* matching dwIndex. Ignore 0.0.0.0 addresses.
*/
+ if (tableP == NULL)
+ return 0;
count = 0;
netaddrP = NULL;
i = 0;
- while (i<tableP->dwNumEntries) {
+ while (i < tableP->dwNumEntries) {
if (tableP->table[i].dwIndex == netifP->dwIndex &&
tableP->table[i].dwAddr != 0) {
@@ -437,33 +446,33 @@
case MIB_IF_TYPE_FDDI:
case MIB_IF_TYPE_LOOPBACK:
case IF_TYPE_IEEE80211:
- /**
- * Contrary to what it seems to indicate, dwBCastAddr doesn't
- * contain the broadcast address but 0 or 1 depending on whether
- * the broadcast address should set the bits of the host part
- * to 0 or 1.
- * Yes, I know it's stupid, but what can I say, it's MSFTs API.
- */
- curr->brdcast.sa4.sin_family = AF_INET;
- if (tableP->table[i].dwBCastAddr == 1)
- curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
- else
- curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
- mask = ntohl(tableP->table[i].dwMask);
- curr->mask = 0;
- while (mask) {
- mask <<= 1;
- curr->mask++;
- }
- break;
+ /**
+ * Contrary to what it seems to indicate, dwBCastAddr doesn't
+ * contain the broadcast address but 0 or 1 depending on whether
+ * the broadcast address should set the bits of the host part
+ * to 0 or 1.
+ * Yes, I know it's stupid, but what can I say, it's MSFTs API.
+ */
+ curr->brdcast.sa4.sin_family = AF_INET;
+ if (tableP->table[i].dwBCastAddr == 1)
+ curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
+ else
+ curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
+ mask = ntohl(tableP->table[i].dwMask);
+ curr->mask = 0;
+ while (mask) {
+ mask <<= 1;
+ curr->mask++;
+ }
+ break;
case MIB_IF_TYPE_PPP:
case MIB_IF_TYPE_SLIP:
default:
- /**
- * these don't have broadcast/subnet
- */
- curr->mask = -1;
- break;
+ /**
+ * these don't have broadcast/subnet
+ */
+ curr->mask = -1;
+ break;
}
curr->next = netaddrP;
@@ -474,10 +483,30 @@
}
*netaddrPP = netaddrP;
+ return count;
+}
+
+
+/*
+ * Enumerate the IP addresses on an interface, using an IP address table
+ * retrieved using GetIPAddrTable and matching based on index.
+ *
+ * Returns the count of addresses, or -1 if error. If no error occurs then
+ * netaddrPP will return a list of netaddr structures with the IP addresses.
+ */
+int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP) {
+ MIB_IPADDRTABLE *tableP;
+ int count;
+ int ret = lookupIPAddrTable(env, &tableP);
+ if (ret < 0) {
+ return NULL;
+ }
+ count = enumAddresses_win_ipaddrtable(env, netifP, netaddrPP, tableP);
free(tableP);
return count;
}
+
/*
* Class: java_net_NetworkInterface
* Method: init
@@ -758,6 +787,50 @@
return netifObj;
}
+
+/*
+ * Class: java_net_NetworkInterface
+ * Method: boundInetAddress0
+ * Signature: (Ljava/net/InetAddress;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0
+ (JNIEnv *env, jclass cls, jobject iaObj)
+{
+ jobject netifObj = NULL;
+ DWORD i;
+
+ int family = getInetAddress_family(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+ if (family == java_net_InetAddress_IPv6) {
+ if (!ipv6_available())
+ return JNI_FALSE;
+ return Java_java_net_NetworkInterface_getByInetAddress0_XP(env, cls, iaObj) != NULL;
+ } else if (family == java_net_InetAddress_IPv4) {
+ jint addr = getInetAddress_addr(env, iaObj);
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+ jboolean found = JNI_FALSE;
+ MIB_IPADDRTABLE *tableP;
+ if (lookupIPAddrTable(env, &tableP) >= 0 && tableP != NULL) {
+ for (i = 0; i < tableP->dwNumEntries; i++) {
+ if (tableP->table[i].dwAddr != 0 &&
+ (unsigned long)addr == ntohl(tableP->table[i].dwAddr)) {
+ found = JNI_TRUE;
+ break;
+ }
+ }
+ }
+ if (tableP != NULL) {
+ free(tableP);
+ }
+ return found;
+ } else {
+ // Unknown address family
+ return JNI_FALSE;
+ }
+}
+
/*
* Class: java_net_NetworkInterface
* Method: getByInetAddress0
@@ -767,11 +840,11 @@
(JNIEnv *env, jclass cls, jobject iaObj)
{
netif *ifList, *curr;
+ MIB_IPADDRTABLE *tableP;
jobject netifObj = NULL;
jint addr = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
- // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
if (ipv6_available()) {
return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
}
@@ -785,42 +858,50 @@
* Enumerate the addresses on each interface until we find a
* matching address.
*/
- curr = ifList;
- while (curr != NULL) {
- int count;
- netaddr *addrList;
- netaddr *addrP;
+ tableP = NULL;
+ if (lookupIPAddrTable(env, &tableP) >= 0) {
+ curr = ifList;
+ while (curr != NULL) {
+ int count;
+ netaddr *addrList;
+ netaddr *addrP;
+
+ /* enumerate the addresses on this interface */
+ count = enumAddresses_win_ipaddrtable(env, curr, &addrList, tableP);
+ if (count < 0) {
+ free_netif(ifList);
+ free(tableP);
+ return NULL;
+ }
- /* enumerate the addresses on this interface */
- count = enumAddresses_win(env, curr, &addrList);
- if (count < 0) {
- free_netif(ifList);
- return NULL;
- }
+ /* iterate through each address */
+ addrP = addrList;
- /* iterate through each address */
- addrP = addrList;
+ while (addrP != NULL) {
+ if ((unsigned long)addr == ntohl(addrP->addr.sa4.sin_addr.s_addr)) {
+ break;
+ }
+ addrP = addrP->next;
+ }
- while (addrP != NULL) {
- if ((unsigned long)addr == ntohl(addrP->addr.sa4.sin_addr.s_addr)) {
+ /*
+ * Address matched so create NetworkInterface for this interface
+ * and address list.
+ */
+ if (addrP != NULL) {
+ /* createNetworkInterface will free addrList */
+ netifObj = createNetworkInterface(env, curr, count, addrList);
break;
}
- addrP = addrP->next;
- }
- /*
- * Address matched so create NetworkInterface for this interface
- * and address list.
- */
- if (addrP != NULL) {
- /* createNetworkInterface will free addrList */
- netifObj = createNetworkInterface(env, curr, count, addrList);
- break;
+ /* on next interface */
+ curr = curr->next;
}
+ }
- /* on next interface */
- curr = curr->next;
- }
+ /* release the IP address table */
+ if (tableP != NULL)
+ free(tableP);
/* release the interface list */
free_netif(ifList);
--- a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,9 @@
* and getByAddress.
*/
+extern int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrPP, MIB_IPADDRTABLE *tableP);
extern int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP);
+extern int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP);
int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);
#ifdef DEBUG
@@ -239,6 +241,7 @@
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
{
DWORD ret;
+ MIB_IPADDRTABLE *tableP;
IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
ULONG len=ipinflen, count=0;
netif *nif=NULL, *dup_nif, *last=NULL, *loopif=NULL, *curr;
@@ -271,10 +274,15 @@
// Retrieve IPv4 addresses with the IP Helper API
curr = *netifPP;
+ ret = lookupIPAddrTable(env, &tableP);
+ if (ret < 0) {
+ return -1;
+ }
while (curr != NULL) {
netaddr *netaddrP;
- ret = enumAddresses_win(env, curr, &netaddrP);
+ ret = enumAddresses_win_ipaddrtable(env, curr, &netaddrP, tableP);
if (ret == -1) {
+ free(tableP);
return -1;
} else if (ret == -2) {
if ((*env)->ExceptionCheck(env)) {
@@ -287,7 +295,7 @@
curr = curr->next;
}
}
-
+ free(tableP);
ret = getAdapters (env, &adapters);
if (ret != ERROR_SUCCESS) {
goto err;
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,6 @@
import javax.swing.JProgressBar;
import javax.swing.JTabbedPane;
import javax.swing.JSlider;
-import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -42,6 +41,7 @@
import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_STATE_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_NAME_PROPERTY;
@@ -129,6 +129,8 @@
valueChanged(ptr);
} else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0) {
selectionChanged(ptr);
+ } else if (name.compareTo(ACCESSIBLE_TABLE_MODEL_CHANGED) == 0) {
+ valueChanged(ptr);
} else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
if (newValue instanceof AccessibleContext) {
activeDescendant = (AccessibleContext)newValue;
--- a/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -214,7 +214,7 @@
splash->maskRequired = 0;
-
+
//TODO: the following is too much of a hack but should work in 90% cases.
// besides we don't use device-dependent drawing, so probably
// that's very fine indeed
@@ -282,9 +282,11 @@
SplashRedrawWindow(Splash * splash) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- SplashUpdateScreenData(splash);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ // drop the reference to the old view and image
+ [splash->window setContentView: nil];
+ SplashUpdateScreenData(splash);
- [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
// NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ?
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: (unsigned char**)&splash->screenData
@@ -311,7 +313,7 @@
size.height /= scaleFactor;
[image setSize: size];
}
-
+
NSImageView * view = [[NSImageView alloc] init];
[view setImage: image];
--- a/src/java.desktop/share/classes/javax/swing/JTable.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/share/classes/javax/swing/JTable.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -5278,7 +5278,8 @@
// Don't start when just a modifier is pressed
int code = e.getKeyCode();
if (code == KeyEvent.VK_SHIFT || code == KeyEvent.VK_CONTROL ||
- code == KeyEvent.VK_ALT) {
+ code == KeyEvent.VK_ALT || code == KeyEvent.VK_META ||
+ code == KeyEvent.VK_ALT_GRAPH) {
return false;
}
// Try to install the editor
@@ -5302,7 +5303,9 @@
// If we have started an editor as a result of the user
// pressing a key and the surrendersFocusOnKeystroke property
// is true, give the focus to the new editor.
- if (getSurrendersFocusOnKeystroke()) {
+ Object prop = getClientProperty("JTable.forceAutoStartsEdit");
+ if (getSurrendersFocusOnKeystroke()
+ || Boolean.TRUE.equals(prop)) {
editorComponent.requestFocus();
}
}
@@ -6668,6 +6671,7 @@
*/
protected AccessibleJTable() {
super();
+ JTable.this.putClientProperty("JTable.forceAutoStartsEdit", true);
JTable.this.addPropertyChangeListener(this);
JTable.this.getSelectionModel().addListSelectionListener(this);
TableColumnModel tcm = JTable.this.getColumnModel();
@@ -7104,15 +7108,12 @@
int row = rowAtPoint(p);
if ((column != -1) && (row != -1)) {
- TableColumn aColumn = getColumnModel().getColumn(column);
- TableCellRenderer renderer = aColumn.getCellRenderer();
- if (renderer == null) {
- Class<?> columnClass = getColumnClass(column);
- renderer = getDefaultRenderer(columnClass);
- }
- Component component = renderer.getTableCellRendererComponent(
- JTable.this, null, false, false,
- row, column);
+ if (row == getEditingRow() && column == getEditingColumn()) {
+ Component editor = getEditorComponent();
+ if (editor instanceof Accessible) {
+ return (Accessible) editor;
+ }
+ }
return new AccessibleJTableCell(JTable.this, row, column,
getAccessibleIndexAt(row, column));
}
@@ -7145,15 +7146,12 @@
int column = getAccessibleColumnAtIndex(i);
int row = getAccessibleRowAtIndex(i);
- TableColumn aColumn = getColumnModel().getColumn(column);
- TableCellRenderer renderer = aColumn.getCellRenderer();
- if (renderer == null) {
- Class<?> columnClass = getColumnClass(column);
- renderer = getDefaultRenderer(columnClass);
- }
- Component component = renderer.getTableCellRendererComponent(
- JTable.this, null, false, false,
- row, column);
+ if (row == getEditingRow() && column == getEditingColumn()) {
+ Component editor = getEditorComponent();
+ if (editor instanceof Accessible) {
+ return (Accessible) editor;
+ }
+ }
return new AccessibleJTableCell(JTable.this, row, column,
getAccessibleIndexAt(row, column));
}
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c Mon Jul 22 11:08:27 2019 +0530
@@ -4622,8 +4622,7 @@
if (image != NULL && image->opaque != NULL &&
image->opaque->error_buf == NULL)
{
- /* Ignore errors here: */
- (void)png_safe_execute(image, png_image_free_function, image);
+ png_image_free_function(image);
image->opaque = NULL;
}
}
--- a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,6 @@
import sun.java2d.pipe.ShapeDrawPipe;
import sun.java2d.pipe.TextPipe;
import sun.java2d.pipe.ValidatePipe;
-import sun.java2d.x11.X11SurfaceData;
import sun.java2d.x11.XSurfaceData;
import sun.font.FontManagerNativeLibrary;
@@ -244,7 +243,7 @@
*/
public static XRWindowSurfaceData createData(X11ComponentPeer peer) {
XRGraphicsConfig gc = getGC(peer);
- return new XRWindowSurfaceData(peer, gc, X11SurfaceData.getSurfaceType(gc, Transparency.OPAQUE));
+ return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
}
/**
--- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2451,14 +2451,14 @@
static jobject get_integer_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
{
- gint intval = NULL;
+ gint intval = 0;
(*fp_g_object_get)(settings, key, &intval, NULL);
return create_Integer(env, intval);
}
static jobject get_boolean_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
{
- gint intval = NULL;
+ gint intval = 0;
(*fp_g_object_get)(settings, key, &intval, NULL);
return create_Boolean(env, intval);
}
--- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c Mon Jul 22 11:08:27 2019 +0530
@@ -324,8 +324,6 @@
/* GDK */
fp_gdk_get_default_root_window =
dl_symbol("gdk_get_default_root_window");
- fp_gdk_window_get_scale_factor =
- dl_symbol("gdk_window_get_scale_factor");
/* Pixbuf */
fp_gdk_pixbuf_new = dl_symbol("gdk_pixbuf_new");
@@ -400,6 +398,8 @@
} else {
fp_gdk_window_create_similar_image_surface =
dl_symbol("gdk_window_create_similar_image_surface");
+ fp_gdk_window_get_scale_factor =
+ dl_symbol("gdk_window_get_scale_factor");
}
gtk3_version_3_14 = !fp_gtk_check_version(3, 14, 0);
@@ -479,8 +479,7 @@
fp_gtk_fixed_new = dl_symbol("gtk_fixed_new");
fp_gtk_handle_box_new = dl_symbol("gtk_handle_box_new");
fp_gtk_image_new = dl_symbol("gtk_image_new");
- fp_gtk_hpaned_new = dl_symbol("gtk_hpaned_new");
- fp_gtk_vpaned_new = dl_symbol("gtk_vpaned_new");
+ fp_gtk_paned_new = dl_symbol("gtk_paned_new");
fp_gtk_scale_new = dl_symbol("gtk_scale_new");
fp_gtk_hscrollbar_new = dl_symbol("gtk_hscrollbar_new");
fp_gtk_vscrollbar_new = dl_symbol("gtk_vscrollbar_new");
@@ -1083,7 +1082,7 @@
case SPLIT_PANE:
if (init_result = (NULL == gtk3_widgets[_GTK_HPANED_TYPE]))
{
- gtk3_widgets[_GTK_HPANED_TYPE] = (*fp_gtk_hpaned_new)();
+ gtk3_widgets[_GTK_HPANED_TYPE] = (*fp_gtk_paned_new)(GTK_ORIENTATION_HORIZONTAL);
}
result = gtk3_widgets[_GTK_HPANED_TYPE];
break;
@@ -1316,7 +1315,7 @@
case VSPLIT_PANE_DIVIDER:
if (init_result = (NULL == gtk3_widgets[_GTK_VPANED_TYPE]))
{
- gtk3_widgets[_GTK_VPANED_TYPE] = (*fp_gtk_vpaned_new)();
+ gtk3_widgets[_GTK_VPANED_TYPE] = (*fp_gtk_paned_new)(GTK_ORIENTATION_VERTICAL);
}
result = gtk3_widgets[_GTK_VPANED_TYPE];
break;
@@ -1436,6 +1435,10 @@
} else if (strcmp(detail, "option") == 0) {
path = createWidgetPath (NULL);
append_element(path, "radio");
+ } else if (strcmp(detail, "paned") == 0) {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, "paned");
+ append_element(path, "separator");
} else {
path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
append_element(path, detail);
@@ -1834,22 +1837,30 @@
{
gtk3_widget = gtk3_get_widget(widget_type);
- GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
-
- fp_gtk_style_context_save (context);
+ GtkStyleContext* context = get_style(widget_type, detail);
GtkStateFlags flags = get_gtk_flags(state_type);
fp_gtk_style_context_set_state(context, GTK_STATE_FLAG_PRELIGHT);
- if (detail != 0) {
+ if (detail != 0 && !(strcmp(detail, "paned") == 0)) {
transform_detail_string(detail, context);
fp_gtk_style_context_add_class (context, "handlebox_bin");
}
- fp_gtk_render_handle(context, cr, x, y, width, height);
- fp_gtk_render_background(context, cr, x, y, width, height);
-
- fp_gtk_style_context_restore (context);
+ if (!(strcmp(detail, "paned") == 0)) {
+ fp_gtk_render_handle(context, cr, x, y, width, height);
+ fp_gtk_render_background(context, cr, x, y, width, height);
+ } else {
+ if (orientation == GTK_ORIENTATION_VERTICAL) {
+ fp_gtk_render_handle(context, cr, x+width/2, y, 2, height);
+ fp_gtk_render_background(context, cr, x+width/2, y, 2, height);
+ } else {
+ fp_gtk_render_handle(context, cr, x, y+height/2, width, 2);
+ fp_gtk_render_background(context, cr, x, y+height/2, width, 2);
+ }
+ }
+
+ disposeOrRestoreContext(context);
}
static void gtk3_paint_hline(WidgetType widget_type, GtkStateType state_type,
@@ -2890,9 +2901,13 @@
jint *ary;
GdkWindow *root = (*fp_gdk_get_default_root_window)();
- int win_scale = (*fp_gdk_window_get_scale_factor)(root);
- pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(
- root, x, y, (int)(width / (float)win_scale + 0.5), (int)(height / (float)win_scale + 0.5));
+ if (gtk3_version_3_10) {
+ int win_scale = (*fp_gdk_window_get_scale_factor)(root);
+ pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(
+ root, x, y, (int) (width / (float) win_scale + 0.5), (int) (height / (float) win_scale + 0.5));
+ } else {
+ pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(root, x, y, width, height);
+ }
if (pixbuf && scale != 1) {
GdkPixbuf *scaledPixbuf;
--- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h Mon Jul 22 11:08:27 2019 +0530
@@ -163,6 +163,7 @@
typedef void GtkProgressBar;
typedef void GtkProgress;
typedef void GtkWidgetPath;
+typedef void GtkPaned;
/* Some real structures */
typedef struct
@@ -503,8 +504,7 @@
static GtkWidget* (*fp_gtk_entry_new)();
static GtkWidget* (*fp_gtk_fixed_new)();
static GtkWidget* (*fp_gtk_handle_box_new)();
-static GtkWidget* (*fp_gtk_hpaned_new)();
-static GtkWidget* (*fp_gtk_vpaned_new)();
+static GtkWidget* (*fp_gtk_paned_new)(GtkOrientation orientation);
static GtkWidget* (*fp_gtk_scale_new)(GtkOrientation orientation,
GtkAdjustment* adjustment);
static GtkWidget* (*fp_gtk_hscrollbar_new)(GtkAdjustment* adjustment);
--- a/src/java.management/share/classes/javax/management/remote/package.html Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.management/share/classes/javax/management/remote/package.html Mon Jul 22 11:08:27 2019 +0530
@@ -67,7 +67,7 @@
the optional part of the <em>JMX Remote API</em>
are not included in the <em>Java SE Platform</em>
but are available from the <em>JMX Remote API
- <a href="http://java.sun.com/products/JavaManagement/download.html">
+ <a href="https://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html">
Reference Implementation</a></em>.</p>
--- a/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,8 @@
for (NSString *realm in realms) {
CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
- if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
+ if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
+ if (realmInfo) CFRelease(realmInfo);
return nil;
}
--- a/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java Mon Jul 22 11:08:27 2019 +0530
@@ -128,8 +128,8 @@
* <pre>
* // Create a context using default credentials
* // and the implementation specific default mechanism
- * GSSManager manager ...
- * GSSName targetName ...
+ * GSSManager manager = ...
+ * GSSName targetName = ...
* GSSContext context = manager.createContext(targetName, null, null,
* GSSContext.INDEFINITE_LIFETIME);
*
@@ -141,21 +141,23 @@
*
* // establish a context between peers
*
- * byte []inToken = new byte[0];
+ * byte[] inToken = new byte[0];
+ * byte[] outToken;
*
* // Loop while there still is a token to be processed
*
* while (!context.isEstablished()) {
*
- * byte[] outToken
- * = context.initSecContext(inToken, 0, inToken.length);
+ * outToken = context.initSecContext(inToken, 0, inToken.length);
*
* // send the output token if generated
- * if (outToken != null)
+ * if (outToken != null) {
* sendToken(outToken);
+ * }
*
* if (!context.isEstablished()) {
* inToken = readToken();
+ * }
* }
*
* // display context information
@@ -165,21 +167,40 @@
* System.out.println("Initiator = " + context.getSrcName());
* System.out.println("Acceptor = " + context.getTargName());
*
- * if (context.getConfState())
- * System.out.println("Confidentiality (i.e., privacy) is available");
+ * if (context.getConfState()) {
+ * System.out.println("Confidentiality (i.e., privacy) is available");
+ * }
*
- * if (context.getIntegState())
- * System.out.println("Integrity is available");
+ * if (context.getIntegState()) {
+ * System.out.println("Integrity is available");
+ * }
*
* // perform wrap on an application supplied message, appMsg,
* // using QOP = 0, and requesting privacy service
- * byte [] appMsg ...
+ * byte[] appMsg = ...
*
* MessageProp mProp = new MessageProp(0, true);
*
- * byte []tok = context.wrap(appMsg, 0, appMsg.length, mProp);
+ * outToken = context.wrap(appMsg, 0, appMsg.length, mProp);
+ *
+ * sendToken(outToken);
+ *
+ * // perform unwrap on an incoming application message, and check
+ * // its privacy state and supplementary information
+ * inToken = readToken();
+ *
+ * mProp = new MessageProp(0, true);
*
- * sendToken(tok);
+ * appMsg = context.unwrap(inToken, 0, inToken.length, mProp);
+ *
+ * System.out.println("Was it encrypted? " + mProp.getPrivacy());
+ * System.out.println("Duplicate Token? " + mProp.isDuplicateToken());
+ * System.out.println("Old Token? " + mProp.isOldToken());
+ * System.out.println("Unsequenced Token? " + mProp.isUnseqToken());
+ * System.out.println("Gap Token? " + mProp.isGapToken());
+ *
+ * // the application determines if the privacy state and supplementary
+ * // information are acceptable
*
* // release the local-end of the context
* context.dispose();
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,82 +58,6 @@
}
/**
- * Retrieve the service ticket for serverPrincipal from caller's Subject
- * or from Subject obtained by logging in, or if not found, via the
- * Ticket Granting Service using the TGT obtained from the Subject.
- *
- * Caller must have permission to:
- * - access and update Subject's private credentials
- * - create LoginContext
- * - read the auth.login.defaultCallbackHandler security property
- *
- * NOTE: This method is used by JSSE Kerberos Cipher Suites
- */
- public static KerberosTicket getTicketFromSubjectAndTgs(GSSCaller caller,
- String clientPrincipal, String serverPrincipal, String tgsPrincipal,
- AccessControlContext acc)
- throws LoginException, KrbException, IOException {
-
- // 1. Try to find service ticket in acc subject
- Subject accSubj = Subject.getSubject(acc);
- KerberosTicket ticket = SubjectComber.find(accSubj,
- serverPrincipal, clientPrincipal, KerberosTicket.class);
-
- if (ticket != null) {
- return ticket; // found it
- }
-
- Subject loginSubj = null;
- if (!GSSUtil.useSubjectCredsOnly(caller)) {
- // 2. Try to get ticket from login
- try {
- loginSubj = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
- ticket = SubjectComber.find(loginSubj,
- serverPrincipal, clientPrincipal, KerberosTicket.class);
- if (ticket != null) {
- return ticket; // found it
- }
- } catch (LoginException e) {
- // No login entry to use
- // ignore and continue
- }
- }
-
- // Service ticket not found in subject or login
- // Try to get TGT to acquire service ticket
-
- // 3. Try to get TGT from acc subject
- KerberosTicket tgt = SubjectComber.find(accSubj,
- tgsPrincipal, clientPrincipal, KerberosTicket.class);
-
- boolean fromAcc;
- if (tgt == null && loginSubj != null) {
- // 4. Try to get TGT from login subject
- tgt = SubjectComber.find(loginSubj,
- tgsPrincipal, clientPrincipal, KerberosTicket.class);
- fromAcc = false;
- } else {
- fromAcc = true;
- }
-
- // 5. Try to get service ticket using TGT
- if (tgt != null) {
- Credentials tgtCreds = ticketToCreds(tgt);
- Credentials serviceCreds = Credentials.acquireServiceCreds(
- serverPrincipal, tgtCreds);
- if (serviceCreds != null) {
- ticket = credsToTicket(serviceCreds);
-
- // Store service ticket in acc's Subject
- if (fromAcc && accSubj != null && !accSubj.isReadOnly()) {
- accSubj.getPrivateCredentials().add(ticket);
- }
- }
- }
- return ticket;
- }
-
- /**
* Retrieves the ticket corresponding to the client/server principal
* pair from the Subject in the specified AccessControlContext.
* If the ticket can not be found in the Subject, and if
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java Mon Jul 22 11:08:27 2019 +0530
@@ -197,6 +197,26 @@
usage);
}
+ // =============== ATTENTION! Use with care ==================
+ // According to https://tools.ietf.org/html/rfc3961#section-6.1,
+ // An unkeyed checksum should only be used "in limited circumstances
+ // where the lack of a key does not provide a window for an attack,
+ // preferably as part of an encrypted message".
+ public boolean verifyAnyChecksum(byte[] data, EncryptionKey key,
+ int usage)
+ throws KdcErrException, KrbCryptoException {
+ CksumType cksumEngine = CksumType.getInstance(cksumType);
+ if (!cksumEngine.isSafe()) {
+ return cksumEngine.verifyChecksum(data, checksum);
+ } else {
+ return cksumEngine.verifyKeyedChecksum(data,
+ data.length,
+ key.getBytes(),
+ checksum,
+ usage);
+ }
+ }
+
/*
public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
this(Checksum.CKSUMTYPE_DEFAULT, data);
--- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbAsReqBuilder.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbAsReqBuilder.java Mon Jul 22 11:08:27 2019 +0530
@@ -367,6 +367,8 @@
paList = kerr.getPA(); // Update current paList
} else {
if (referralsState.handleError(ke)) {
+ pakey = null;
+ preAuthFailedOnce = false;
continue;
}
throw ke;
--- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java Mon Jul 22 11:08:27 2019 +0530
@@ -158,8 +158,10 @@
Checksum repCksum = new Checksum(
new DerInputStream(
pa.getValue()).getDerValue());
+ // The checksum is inside encKDCRepPart so we don't
+ // care if it's keyed or not.
repPaReqEncPaRepValid =
- repCksum.verifyKeyedChecksum(
+ repCksum.verifyAnyChecksum(
req.asn1Encode(), replyKey,
KeyUsage.KU_AS_REQ);
} catch (Exception e) {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java Mon Jul 22 11:08:27 2019 +0530
@@ -156,6 +156,11 @@
public abstract byte[] calculateKeyedChecksum(byte[] data, int size,
byte[] key, int usage) throws KrbCryptoException;
+ public boolean verifyChecksum(byte[] data, byte[] checksum)
+ throws KrbCryptoException {
+ throw new UnsupportedOperationException("Not supported");
+ }
+
public abstract boolean verifyKeyedChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException;
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java Mon Jul 22 11:08:27 2019 +0530
@@ -101,4 +101,14 @@
return false;
}
+ @Override
+ public boolean verifyChecksum(byte[] data, byte[] checksum)
+ throws KrbCryptoException {
+ try {
+ byte[] calculated = MessageDigest.getInstance("MD5").digest(data);
+ return CksumType.isChecksumEqual(calculated, checksum);
+ } catch (Exception e) {
+ return false;
+ }
+ }
}
--- a/src/java.security.jgss/share/native/libj2gss/NativeFunc.h Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/native/libj2gss/NativeFunc.h Mon Jul 22 11:08:27 2019 +0530
@@ -57,8 +57,8 @@
typedef OM_uint32 (*IMPORT_NAME_FN_PTR)
(OM_uint32 *minor_status,
- const gss_buffer_t input_name_buffer,
- const gss_OID input_name_type,
+ gss_const_buffer_t input_name_buffer,
+ gss_const_OID input_name_type,
gss_name_t *output_name);
typedef OM_uint32 (*COMPARE_NAME_FN_PTR)
@@ -70,7 +70,7 @@
typedef OM_uint32 (*CANONICALIZE_NAME_FN_PTR)
(OM_uint32 *minor_status,
gss_const_name_t input_name,
- const gss_OID mech_type,
+ gss_const_OID mech_type,
gss_name_t *output_name);
typedef OM_uint32 (*EXPORT_NAME_FN_PTR)
@@ -88,7 +88,7 @@
(OM_uint32 *minor_status,
gss_const_name_t desired_name,
OM_uint32 time_req,
- const gss_OID_set desired_mech,
+ gss_const_OID_set desired_mech,
gss_cred_usage_t cred_usage,
gss_cred_id_t *output_cred_handle,
gss_OID_set *actual_mechs,
@@ -108,7 +108,7 @@
typedef OM_uint32 (*IMPORT_SEC_CONTEXT_FN_PTR)
(OM_uint32 *minor_status,
- const gss_buffer_t interprocess_token,
+ gss_const_buffer_t interprocess_token,
gss_ctx_id_t *context_handle);
typedef OM_uint32 (*INIT_SEC_CONTEXT_FN_PTR)
@@ -116,11 +116,11 @@
gss_const_cred_id_t initiator_cred_handle,
gss_ctx_id_t *context_handle,
gss_const_name_t target_name,
- const gss_OID mech_type,
+ gss_const_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
- const gss_buffer_t input_token,
+ gss_const_channel_bindings_t input_chan_bindings,
+ gss_const_buffer_t input_token,
gss_OID *actual_mech_type,
gss_buffer_t output_token,
OM_uint32 *ret_flags,
@@ -130,8 +130,8 @@
(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
gss_const_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token,
- const gss_channel_bindings_t input_chan_bindings,
+ gss_const_buffer_t input_token,
+ gss_const_channel_bindings_t input_chan_bindings,
gss_name_t *src_name,
gss_OID *mech_type,
gss_buffer_t output_token,
@@ -177,14 +177,14 @@
(OM_uint32 *minor_status,
gss_const_ctx_id_t context_handle,
gss_qop_t qop_req,
- const gss_buffer_t message_buffer,
+ gss_const_buffer_t message_buffer,
gss_buffer_t msg_token);
typedef OM_uint32 (*VERIFY_MIC_FN_PTR)
(OM_uint32 *minor_status,
gss_const_ctx_id_t context_handle,
- const gss_buffer_t message_buffer,
- const gss_buffer_t token_buffer,
+ gss_const_buffer_t message_buffer,
+ gss_const_buffer_t token_buffer,
gss_qop_t *qop_state);
typedef OM_uint32 (*WRAP_FN_PTR)
@@ -192,14 +192,14 @@
gss_const_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
- const gss_buffer_t input_message_buffer,
+ gss_const_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer);
typedef OM_uint32 (*UNWRAP_FN_PTR)
(OM_uint32 *minor_status,
gss_const_ctx_id_t context_handle,
- const gss_buffer_t input_message_buffer,
+ gss_const_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state);
@@ -210,19 +210,19 @@
typedef OM_uint32 (*INQUIRE_NAMES_FOR_MECH_FN_PTR)
(OM_uint32 *minor_status,
- const gss_OID mechanism,
+ gss_const_OID mechanism,
gss_OID_set *name_types);
typedef OM_uint32 (*ADD_OID_SET_MEMBER_FN_PTR)
(OM_uint32 *minor_status,
- const gss_OID member_oid,
+ gss_const_OID member_oid,
gss_OID_set *oid_set);
typedef OM_uint32 (*DISPLAY_STATUS_FN_PTR)
(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
- const gss_OID mech_type,
+ gss_const_OID mech_type,
OM_uint32 *message_context,
gss_buffer_t status_string);
--- a/src/java.security.jgss/share/native/libj2gss/gssapi.h Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/share/native/libj2gss/gssapi.h Mon Jul 22 11:08:27 2019 +0530
@@ -404,7 +404,7 @@
OM_uint32 *, /* minor_status */
gss_const_name_t, /* desired_name */
OM_uint32, /* time_req */
- const gss_OID_set, /* desired_mechs */
+ gss_const_OID_set, /* desired_mechs */
gss_cred_usage_t, /* cred_usage */
gss_cred_id_t *, /* output_cred_handle */
gss_OID_set *, /* actual_mechs */
@@ -421,11 +421,11 @@
gss_const_cred_id_t, /* claimant_cred_handle */
gss_ctx_id_t *, /* context_handle */
gss_const_name_t, /* target_name */
- const gss_OID, /* mech_type */
+ gss_const_OID, /* mech_type */
OM_uint32, /* req_flags */
OM_uint32, /* time_req */
- const gss_channel_bindings_t, /* input_chan_bindings */
- const gss_buffer_t, /* input_token */
+ gss_const_channel_bindings_t, /* input_chan_bindings */
+ gss_const_buffer_t, /* input_token */
gss_OID *, /* actual_mech_type */
gss_buffer_t, /* output_token */
OM_uint32 *, /* ret_flags */
@@ -436,8 +436,8 @@
OM_uint32 *, /* minor_status */
gss_ctx_id_t *, /* context_handle */
gss_const_cred_id_t, /* acceptor_cred_handle */
- const gss_buffer_t, /* input_token_buffer */
- const gss_channel_bindings_t, /* input_chan_bindings */
+ gss_const_buffer_t, /* input_token_buffer */
+ gss_const_channel_bindings_t, /* input_chan_bindings */
gss_name_t *, /* src_name */
gss_OID *, /* mech_type */
gss_buffer_t, /* output_token */
@@ -449,7 +449,7 @@
GSS_DLLIMP OM_uint32 gss_process_context_token(
OM_uint32 *, /* minor_status */
gss_const_ctx_id_t, /* context_handle */
- const gss_buffer_t /* token_buffer */
+ gss_const_buffer_t /* token_buffer */
);
GSS_DLLIMP OM_uint32 gss_delete_sec_context(
@@ -469,7 +469,7 @@
OM_uint32 *, /* minor_status */
gss_const_ctx_id_t, /* context_handle */
gss_qop_t, /* qop_req */
- const gss_buffer_t, /* message_buffer */
+ gss_const_buffer_t, /* message_buffer */
gss_buffer_t /* message_token */
);
@@ -477,8 +477,8 @@
GSS_DLLIMP OM_uint32 gss_verify_mic(
OM_uint32 *, /* minor_status */
gss_const_ctx_id_t, /* context_handle */
- const gss_buffer_t, /* message_buffer */
- const gss_buffer_t, /* message_token */
+ gss_const_buffer_t, /* message_buffer */
+ gss_const_buffer_t, /* message_token */
gss_qop_t * /* qop_state */
);
@@ -488,7 +488,7 @@
gss_const_ctx_id_t, /* context_handle */
int, /* conf_req_flag */
gss_qop_t, /* qop_req */
- const gss_buffer_t, /* input_message_buffer */
+ gss_const_buffer_t, /* input_message_buffer */
int *, /* conf_state */
gss_buffer_t /* output_message_buffer */
);
@@ -497,7 +497,7 @@
GSS_DLLIMP OM_uint32 gss_unwrap(
OM_uint32 *, /* minor_status */
gss_const_ctx_id_t, /* context_handle */
- const gss_buffer_t, /* input_message_buffer */
+ gss_const_buffer_t, /* input_message_buffer */
gss_buffer_t, /* output_message_buffer */
int *, /* conf_state */
gss_qop_t * /* qop_state */
@@ -507,7 +507,7 @@
OM_uint32 *, /* minor_status */
OM_uint32, /* status_value */
int, /* status_type */
- const gss_OID, /* mech_type (used to be const) */
+ gss_const_OID, /* mech_type (used to be const) */
OM_uint32 *, /* message_context */
gss_buffer_t /* status_string */
);
@@ -533,8 +533,8 @@
GSS_DLLIMP OM_uint32 gss_import_name(
OM_uint32 *, /* minor_status */
- const gss_buffer_t, /* input_name_buffer */
- const gss_OID, /* input_name_type(used to be const) */
+ gss_const_buffer_t, /* input_name_buffer */
+ gss_const_OID, /* input_name_type(used to be const) */
gss_name_t * /* output_name */
);
@@ -590,7 +590,7 @@
OM_uint32 *, /* minor_status */
gss_const_cred_id_t, /* input_cred_handle */
gss_const_name_t, /* desired_name */
- const gss_OID, /* desired_mech */
+ gss_const_OID, /* desired_mech */
gss_cred_usage_t, /* cred_usage */
OM_uint32, /* initiator_time_req */
OM_uint32, /* acceptor_time_req */
@@ -604,7 +604,7 @@
GSS_DLLIMP OM_uint32 gss_inquire_cred_by_mech(
OM_uint32 *, /* minor_status */
gss_const_cred_id_t, /* cred_handle */
- const gss_OID, /* mech_type */
+ gss_const_OID, /* mech_type */
gss_name_t *, /* name */
OM_uint32 *, /* initiator_lifetime */
OM_uint32 *, /* acceptor_lifetime */
@@ -621,7 +621,7 @@
/* New for V2 */
GSS_DLLIMP OM_uint32 gss_import_sec_context(
OM_uint32 *, /* minor_status */
- const gss_buffer_t, /* interprocess_token */
+ gss_const_buffer_t, /* interprocess_token */
gss_ctx_id_t * /* context_handle */
);
@@ -640,22 +640,22 @@
/* New for V2 */
GSS_DLLIMP OM_uint32 gss_add_oid_set_member(
OM_uint32 *, /* minor_status */
- const gss_OID, /* member_oid */
+ gss_const_OID, /* member_oid */
gss_OID_set * /* oid_set */
);
/* New for V2 */
GSS_DLLIMP OM_uint32 gss_test_oid_set_member(
OM_uint32 *, /* minor_status */
- const gss_OID, /* member */
- const gss_OID_set, /* set */
+ gss_const_OID, /* member */
+ gss_const_OID_set, /* set */
int * /* present */
);
/* New for V2 */
GSS_DLLIMP OM_uint32 gss_str_to_oid(
OM_uint32 *, /* minor_status */
- const gss_buffer_t, /* oid_str */
+ gss_const_buffer_t, /* oid_str */
gss_OID * /* oid */
);
@@ -669,7 +669,7 @@
/* New for V2 */
GSS_DLLIMP OM_uint32 gss_inquire_names_for_mech(
OM_uint32 *, /* minor_status */
- const gss_OID, /* mechanism */
+ gss_const_OID, /* mechanism */
gss_OID_set * /* name_types */
);
@@ -691,7 +691,7 @@
GSS_DLLIMP OM_uint32 gss_canonicalize_name(
OM_uint32 *, /* minor_status */
gss_const_name_t, /* input_name */
- const gss_OID, /* mech_type */
+ gss_const_OID, /* mech_type */
gss_name_t * /* output_name */
);
--- a/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -209,14 +209,14 @@
}
static BOOLEAN
-is_same_oid(gss_OID o2, gss_OID o1)
+is_same_oid(gss_const_OID o2, gss_const_OID o1)
{
return o1 && o2 && o1->length == o2->length
&& !memcmp(o1->elements, o2->elements, o2->length);
}
static BOOLEAN
-has_oid(gss_OID_set set, gss_OID oid)
+has_oid(gss_const_OID_set set, gss_const_OID oid)
{
for (int i = 0; i < set->count; i++) {
if (is_same_oid(&set->elements[i], oid)) {
@@ -227,7 +227,7 @@
}
static void
-get_oid_desc(gss_OID mech)
+show_oid(gss_const_OID mech)
{
if (trace) {
if (is_same_oid(mech, &KRB5_OID)) {
@@ -249,7 +249,7 @@
}
static void
-get_oid_set_desc(gss_OID_set mechs)
+show_oid_set(gss_const_OID_set mechs)
{
if (trace) {
if (mechs == NULL) {
@@ -258,7 +258,7 @@
}
PP("gss_OID_set.count is %d", (int)mechs->count);
for (int i = 0; i < mechs->count; i++) {
- get_oid_desc(&mechs->elements[i]);
+ show_oid(&mechs->elements[i]);
}
}
}
@@ -332,8 +332,8 @@
__declspec(dllexport) OM_uint32
gss_import_name(OM_uint32 *minor_status,
- const gss_buffer_t input_name_buffer,
- const gss_OID input_name_type,
+ gss_const_buffer_t input_name_buffer,
+ gss_const_OID input_name_type,
gss_name_t *output_name)
{
PP(">>>> Calling gss_import_name...");
@@ -344,6 +344,9 @@
LPSTR input = (LPSTR)input_name_buffer->value;
if (input_name_type != NULL
&& is_same_oid(input_name_type, &EXPORT_NAME_OID)) {
+ if (len < 4 || input[0] != 4 || input[1] != 1 || input[2] != 0) {
+ return GSS_S_FAILURE;
+ }
int mechLen = (int)input[3]; /* including 06 len */
len -= mechLen + 8; /* 4 header bytes, and an int32 length after OID */
if (len <= 0) {
@@ -429,15 +432,50 @@
SEC_WCHAR* n1 = name1->name;
SEC_WCHAR* n2 = name2->name;
PP("Comparing %ls and %ls", n1, n2);
+
int l1 = lstrlen(n1);
int l2 = lstrlen(n2);
- if (l1 < l2 && n2[l1] != L'@'
- || l2 < l1 && n1[l2] != L'@') {
+ int r1 = l1; // position of @ or the end if none
+ int r2 = l2;
+ int i;
+
+ for (i = 0; i < l1; i++) {
+ if (n1[i] == L'\\') {
+ i++;
+ continue;
+ }
+ if (n1[i] == L'@') {
+ r1 = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < l2; i++) {
+ if (n2[i] == L'\\') {
+ i++;
+ continue;
+ }
+ if (n2[i] == L'@') {
+ r2 = i;
+ break;
+ }
+ }
+
+ if (l1 < l2 && l1 != r2
+ || l2 < l1 && l2 != l1) {
return GSS_S_COMPLETE; // different
}
+
if (l1 > l2) {
l1 = l2; // choose the smaller one. longer=smaller @ ...
}
+
+ // Two names are equal if they are the same or one has no realm and
+ // one has realm but they have the same name. If both have realm but
+ // different, they are treated different even if the names are the same.
+ // Note: the default name concept is not used here.
+ // Principal names on Windows are case-insensitive, both user name
+ // and service principal name.
if (CompareStringEx(LOCALE_NAME_SYSTEM_DEFAULT, NORM_IGNORECASE,
n1, l1, n2, l1, NULL, NULL, 0) == CSTR_EQUAL) {
*name_equal = 1;
@@ -448,7 +486,7 @@
__declspec(dllexport) OM_uint32
gss_canonicalize_name(OM_uint32 *minor_status,
gss_const_name_t input_name,
- const gss_OID mech_type,
+ gss_const_OID mech_type,
gss_name_t *output_name)
{
PP(">>>> Calling gss_canonicalize_name...");
@@ -456,6 +494,10 @@
CHECK_OID(mech_type)
CHECK_OUTPUT(output_name)
+ if (!is_same_oid(mech_type, &KRB5_OID)) {
+ PP("Cannot canonicalize to non-krb5 OID");
+ return GSS_S_BAD_MECH;
+ }
gss_name_t names2 = new gss_name_struct;
if (names2 == NULL) {
return GSS_S_FAILURE;
@@ -558,7 +600,7 @@
gss_acquire_cred(OM_uint32 *minor_status,
gss_const_name_t desired_name,
OM_uint32 time_req,
- const gss_OID_set desired_mechs,
+ gss_const_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
gss_cred_id_t *output_cred_handle,
gss_OID_set *actual_mechs,
@@ -572,7 +614,7 @@
ts.QuadPart = 0;
cred_usage = 0;
PP("AcquireCredentialsHandle with %d %p", cred_usage, desired_mechs);
- get_oid_set_desc(desired_mechs);
+ show_oid_set(desired_mechs);
BOOLEAN reqKerberos, reqSPNEGO;
@@ -787,7 +829,7 @@
__declspec(dllexport) OM_uint32
gss_import_sec_context(OM_uint32 *minor_status,
- const gss_buffer_t interprocess_token,
+ gss_const_buffer_t interprocess_token,
gss_ctx_id_t *context_handle)
{
// Not transferable, return FAILURE
@@ -801,11 +843,11 @@
gss_const_cred_id_t initiator_cred_handle,
gss_ctx_id_t *context_handle,
gss_const_name_t target_name,
- const gss_OID mech_type,
+ gss_const_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
- const gss_buffer_t input_token,
+ gss_const_channel_bindings_t input_chan_bindings,
+ gss_const_buffer_t input_token,
gss_OID *actual_mech_type,
gss_buffer_t output_token,
OM_uint32 *ret_flags,
@@ -927,7 +969,6 @@
&lifeTime);
if (!SEC_SUCCESS(ss)) {
- // TODO: seems NativeGSSContext has not failed here.
PP("InitializeSecurityContext failed");
goto err;
}
@@ -983,8 +1024,8 @@
gss_accept_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
gss_const_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token,
- const gss_channel_bindings_t input_chan_bindings,
+ gss_const_buffer_t input_token,
+ gss_const_channel_bindings_t input_chan_bindings,
gss_name_t *src_name,
gss_OID *mech_type,
gss_buffer_t output_token,
@@ -1168,13 +1209,13 @@
gss_get_mic(OM_uint32 *minor_status,
gss_const_ctx_id_t context_handle,
gss_qop_t qop_req,
- const gss_buffer_t message_buffer,
+ gss_const_buffer_t message_buffer,
gss_buffer_t msg_token)
{
PP(">>>> Calling gss_get_mic...");
- CHECK_CONTEXT(context_handle);
- CHECK_BUFFER(message_buffer);
- CHECK_OUTPUT(msg_token);
+ CHECK_CONTEXT(context_handle)
+ CHECK_BUFFER(message_buffer)
+ CHECK_OUTPUT(msg_token)
SECURITY_STATUS ss;
SecBufferDesc buffDesc;
@@ -1208,14 +1249,14 @@
__declspec(dllexport) OM_uint32
gss_verify_mic(OM_uint32 *minor_status,
gss_const_ctx_id_t context_handle,
- const gss_buffer_t message_buffer,
- const gss_buffer_t token_buffer,
+ gss_const_buffer_t message_buffer,
+ gss_const_buffer_t token_buffer,
gss_qop_t *qop_state)
{
PP(">>>> Calling gss_verify_mic...");
- CHECK_CONTEXT(context_handle);
- CHECK_BUFFER(message_buffer);
- CHECK_BUFFER(token_buffer);
+ CHECK_CONTEXT(context_handle)
+ CHECK_BUFFER(message_buffer)
+ CHECK_BUFFER(token_buffer)
SECURITY_STATUS ss;
SecBufferDesc buffDesc;
@@ -1253,14 +1294,14 @@
gss_const_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
- const gss_buffer_t input_message_buffer,
+ gss_const_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer)
{
PP(">>>> Calling gss_wrap...");
- CHECK_CONTEXT(context_handle);
- CHECK_BUFFER(input_message_buffer);
- CHECK_OUTPUT(output_message_buffer);
+ CHECK_CONTEXT(context_handle)
+ CHECK_BUFFER(input_message_buffer)
+ CHECK_OUTPUT(output_message_buffer)
SECURITY_STATUS ss;
SecBufferDesc buffDesc;
@@ -1323,15 +1364,15 @@
__declspec(dllexport) OM_uint32
gss_unwrap(OM_uint32 *minor_status,
gss_const_ctx_id_t context_handle,
- const gss_buffer_t input_message_buffer,
+ gss_const_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state)
{
PP(">>>> Calling gss_unwrap...");
- CHECK_CONTEXT(context_handle);
- CHECK_BUFFER(input_message_buffer);
- CHECK_OUTPUT(output_message_buffer);
+ CHECK_CONTEXT(context_handle)
+ CHECK_BUFFER(input_message_buffer)
+ CHECK_OUTPUT(output_message_buffer)
SECURITY_STATUS ss;
SecBufferDesc buffDesc;
@@ -1417,11 +1458,11 @@
__declspec(dllexport) OM_uint32
gss_inquire_names_for_mech(OM_uint32 *minor_status,
- const gss_OID mechanism,
+ gss_const_OID mechanism,
gss_OID_set *name_types)
{
PP(">>>> Calling gss_inquire_names_for_mech...");
- CHECK_OID(mechanism);
+ CHECK_OID(mechanism)
if (gss_create_empty_oid_set(minor_status, name_types)) {
return GSS_S_FAILURE;
@@ -1445,12 +1486,12 @@
__declspec(dllexport) OM_uint32
gss_add_oid_set_member(OM_uint32 *minor_status,
- const gss_OID member_oid,
+ gss_const_OID member_oid,
gss_OID_set *oid_set)
{
PP(">>>> Calling gss_add_oid_set_member...");
- CHECK_OID(member_oid);
- CHECK_OUTPUT(oid_set);
+ CHECK_OID(member_oid)
+ CHECK_OUTPUT(oid_set)
int count = (int)(*oid_set)->count;
@@ -1490,7 +1531,7 @@
gss_display_status(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
- const gss_OID mech_type,
+ gss_const_OID mech_type,
OM_uint32 *message_context,
gss_buffer_t status_string)
{
@@ -1526,7 +1567,7 @@
gss_OID_set *oid_set)
{
PP(">>>> Calling gss_create_empty_oid_set...");
- CHECK_OUTPUT(oid_set);
+ CHECK_OUTPUT(oid_set)
if (*oid_set = new gss_OID_set_desc) {
memset(*oid_set, 0, sizeof(gss_OID_set_desc));
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -42,6 +42,7 @@
import java.util.StringTokenizer;
import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogFeatures;
+import jdk.xml.internal.ErrorHandlerProxy;
import jdk.xml.internal.JdkXmlFeatures;
import jdk.xml.internal.JdkXmlUtils;
import jdk.xml.internal.SecuritySupport;
@@ -61,7 +62,7 @@
* @author G. Todd Miller
* @author Morten Jorgensen
* @author Erwin Bolwidt <ejb@klomp.org>
- * @LastModified: Nov 2017
+ * @LastModified: July 2019
*/
public class Parser implements Constants, ContentHandler {
@@ -98,9 +99,13 @@
private boolean _overrideDefaultParser;
- public Parser(XSLTC xsltc, boolean useOverrideDefaultParser) {
+ // flag indicates whether there's an user's ErrorListener
+ private boolean _hasUserErrListener;
+
+ public Parser(XSLTC xsltc, boolean useOverrideDefaultParser, boolean hasUserErrListener) {
_xsltc = xsltc;
_overrideDefaultParser = useOverrideDefaultParser;
+ _hasUserErrListener = hasUserErrListener;
}
public void init() {
@@ -426,6 +431,11 @@
try {
// Parse the input document and build the abstract syntax tree
reader.setContentHandler(this);
+ if (_hasUserErrListener) {
+ // Set a ErrorHandler proxy to pass any parsing error on to be handled
+ // by the user's ErrorListener
+ reader.setErrorHandler(new ErrorHandlerProxy());
+ }
reader.parse(input);
// Find the start of the stylesheet within the tree
return getStylesheet(_root);
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -58,7 +58,7 @@
* @author G. Todd Miller
* @author Morten Jorgensen
* @author John Howard (johnh@schemasoft.com)
- * @LastModified: Oct 2017
+ * @LastModified: July 2019
*/
public final class XSLTC {
@@ -175,10 +175,10 @@
/**
* XSLTC compiler constructor
*/
- public XSLTC(JdkXmlFeatures featureManager) {
+ public XSLTC(JdkXmlFeatures featureManager, boolean hasListener) {
_overrideDefaultParser = featureManager.getFeature(
JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER);
- _parser = new Parser(this, _overrideDefaultParser);
+ _parser = new Parser(this, _overrideDefaultParser, hasListener);
_xmlFeatures = featureManager;
_extensionClassLoader = null;
_externalExtensionFunctions = new HashMap<>();
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -75,7 +75,7 @@
/**
* @author Jacek Ambroziak
* @author Santiago Pericas-Geertsen
- * @LastModified: Nov 2017
+ * @LastModified: July 2019
*/
public class MethodGenerator extends MethodGen
implements com.sun.org.apache.xalan.internal.xsltc.compiler.Constants {
@@ -207,7 +207,7 @@
_nextNode = new INVOKEINTERFACE(index, 1);
_slotAllocator = new SlotAllocator();
- _slotAllocator.initialize(getLocalVariableRegistry().getLocals(false));
+ _slotAllocator.initialize(getLocalVariableRegistry().getLocals());
_allocatorInit = true;
}
@@ -445,7 +445,7 @@
}
}
} else {
- _nameToLVGMap.remove(lvg);
+ _nameToLVGMap.remove(lvg.getName());
}
}
@@ -480,55 +480,31 @@
}
/**
- * <p>Gets all {@link LocalVariableGen} objects for this method.</p>
- * <p>When the <code>includeRemoved</code> argument has the value
- * <code>false</code>, this method replaces uses of
- * {@link MethodGen#getLocalVariables()} which has
+ * Gets all {@link LocalVariableGen} objects.
+ * This method replaces {@link MethodGen#getLocalVariables()} which has
* a side-effect of setting the start and end range for any
- * <code>LocalVariableGen</code> if either was <code>null</code>. That
+ * {@code LocalVariableGen} if either was {@code null}. That
* side-effect causes problems for outlining of code in XSLTC.
- * @param includeRemoved Specifies whether all local variables ever
- * declared should be returned (<code>true</code>) or only those not
- * removed (<code>false</code>)
- * @return an array of <code>LocalVariableGen</code> containing all the
+ *
+ * @return an array of {@code LocalVariableGen} containing all the
* local variables
*/
@SuppressWarnings("unchecked")
- protected LocalVariableGen[] getLocals(boolean includeRemoved) {
+ private LocalVariableGen[] getLocals() {
LocalVariableGen[] locals = null;
List<LocalVariableGen> allVarsEverDeclared = new ArrayList<>();
- if (includeRemoved) {
- int slotCount = allVarsEverDeclared.size();
-
- for (int i = 0; i < slotCount; i++) {
- Object slotEntries = _variables.get(i);
- if (slotEntries != null) {
- if (slotEntries instanceof ArrayList) {
- List<LocalVariableGen> slotList =
- (List<LocalVariableGen>)slotEntries;
-
- for (int j = 0; j < slotList.size(); j++) {
- allVarsEverDeclared.add(slotList.get(i));
- }
- } else {
- allVarsEverDeclared.add((LocalVariableGen)slotEntries);
+ for (Map.Entry<String, Object> nameVarsPair : _nameToLVGMap.entrySet()) {
+ Object vars = nameVarsPair.getValue();
+ if (vars != null) {
+ if (vars instanceof ArrayList) {
+ List<LocalVariableGen> varsList =
+ (List<LocalVariableGen>) vars;
+ for (int i = 0; i < varsList.size(); i++) {
+ allVarsEverDeclared.add(varsList.get(i));
}
- }
- }
- } else {
- for (Map.Entry<String, Object> nameVarsPair : _nameToLVGMap.entrySet()) {
- Object vars = nameVarsPair.getValue();
- if (vars != null) {
- if (vars instanceof ArrayList) {
- List<LocalVariableGen> varsList =
- (List<LocalVariableGen>) vars;
- for (int i = 0; i < varsList.size(); i++) {
- allVarsEverDeclared.add(varsList.get(i));
- }
- } else {
- allVarsEverDeclared.add((LocalVariableGen)vars);
- }
+ } else {
+ allVarsEverDeclared.add((LocalVariableGen)vars);
}
}
}
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -119,25 +119,41 @@
try {
// remembers the nest level of elements to know when we are done.
int depth=0;
+ boolean startedAtDocument = false;
// skip over START_DOCUMENT
int event = staxStreamReader.getEventType();
if (event == XMLStreamConstants.START_DOCUMENT) {
+ startedAtDocument = true;
event = staxStreamReader.next();
}
- // If not a START_ELEMENT (e.g., a DTD), skip to next tag
- if (event != XMLStreamConstants.START_ELEMENT) {
- event = staxStreamReader.nextTag();
- // An error if a START_ELEMENT isn't found now
- if (event != XMLStreamConstants.START_ELEMENT) {
- throw new IllegalStateException("The current event is " +
- "not START_ELEMENT\n but" + event);
+ handleStartDocument();
+
+ // Handle the prolog: http://www.w3.org/TR/REC-xml/#NT-prolog
+ while (event != XMLStreamConstants.START_ELEMENT) {
+ switch (event) {
+ case XMLStreamConstants.CHARACTERS :
+ handleCharacters();
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION :
+ handlePI();
+ break;
+ case XMLStreamConstants.COMMENT :
+ handleComment();
+ break;
+ case XMLStreamConstants.DTD :
+ handleDTD();
+ break;
+ case XMLStreamConstants.SPACE :
+ handleSpace();
+ break;
+ default :
+ throw new InternalError("processing prolog event: " + event);
}
+ event=staxStreamReader.next();
}
- handleStartDocument();
-
do {
// These are all of the events listed in the javadoc for
// XMLEvent.
@@ -191,6 +207,29 @@
event=staxStreamReader.next();
} while (depth!=0);
+ if (startedAtDocument) {
+ // Handle the Misc (http://www.w3.org/TR/REC-xml/#NT-Misc) that can follow the document element
+ while (event != XMLStreamConstants.END_DOCUMENT) {
+ switch (event) {
+ case XMLStreamConstants.CHARACTERS :
+ handleCharacters();
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION :
+ handlePI();
+ break;
+ case XMLStreamConstants.COMMENT :
+ handleComment();
+ break;
+ case XMLStreamConstants.SPACE :
+ handleSpace();
+ break;
+ default :
+ throw new InternalError("processing misc event after document element: " + event);
+ }
+ event=staxStreamReader.next();
+ }
+ }
+
handleEndDocument();
} catch (SAXException e) {
throw new XMLStreamException(e);
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -47,6 +47,7 @@
* Implementation of a JAXP1.1 TemplatesHandler
* @author Morten Jorgensen
* @author Santiago Pericas-Geertsen
+ * @LastModified: July 2019
*/
public class TemplatesHandlerImpl
implements ContentHandler, TemplatesHandler, SourceLoader
@@ -91,14 +92,14 @@
/**
* Default constructor
*/
- protected TemplatesHandlerImpl(int indentNumber,
- TransformerFactoryImpl tfactory)
+ protected TemplatesHandlerImpl(int indentNumber, TransformerFactoryImpl tfactory,
+ boolean hasUserErrListener)
{
_indentNumber = indentNumber;
_tfactory = tfactory;
// Instantiate XSLTC and get reference to parser object
- XSLTC xsltc = new XSLTC(tfactory.getJdkXmlFeatures());
+ XSLTC xsltc = new XSLTC(tfactory.getJdkXmlFeatures(), hasUserErrListener);
if (tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING))
xsltc.setSecureProcessing(true);
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -84,7 +84,7 @@
* @author G. Todd Miller
* @author Morten Jorgensen
* @author Santiago Pericas-Geertsen
- * @LastModified: July 2018
+ * @LastModified: July 2019
*/
public class TransformerFactoryImpl
extends SAXTransformerFactory implements SourceLoader, ErrorListener
@@ -107,6 +107,9 @@
*/
private ErrorListener _errorListener = this;
+ // flag indicating whether there's an user's ErrorListener
+ private boolean _hasUserErrListener;
+
/**
* This URIResolver is passed to all created Templates and Transformers
*/
@@ -297,6 +300,7 @@
"TransformerFactory");
throw new IllegalArgumentException(err.toString());
}
+ _hasUserErrListener = true;
_errorListener = listener;
}
@@ -946,7 +950,7 @@
}
// Create and initialize a stylesheet compiler
- final XSLTC xsltc = new XSLTC(_xmlFeatures);
+ final XSLTC xsltc = new XSLTC(_xmlFeatures, _hasUserErrListener);
if (_debug) xsltc.setDebug(true);
if (_enableInlining)
xsltc.setTemplateInlining(true);
@@ -1104,7 +1108,7 @@
// through the factory instance
buildCatalogFeatures();
final TemplatesHandlerImpl handler =
- new TemplatesHandlerImpl(_indentNumber, this);
+ new TemplatesHandlerImpl(_indentNumber, this, _hasUserErrListener);
if (_uriResolver != null) {
handler.setURIResolver(_uriResolver);
}
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,6 @@
cvc-complex-type.2.4.b = cvc-complex-type.2.4.b: \u8981\u7D20''{0}''\u306E\u30B3\u30F3\u30C6\u30F3\u30C4\u306F\u4E0D\u5B8C\u5168\u3067\u3059\u3002''{1}''\u306E\u3044\u305A\u308C\u304B\u304C\u5FC5\u8981\u3067\u3059\u3002
cvc-complex-type.2.4.c = cvc-complex-type.2.4.c: \u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u306E\u4E00\u81F4\u306F\u53B3\u5BC6\u3067\u3059\u304C\u3001\u8981\u7D20''{0}''\u3067\u5BA3\u8A00\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002
cvc-complex-type.2.4.d = cvc-complex-type.2.4.d: \u8981\u7D20''{0}''\u3067\u59CB\u307E\u308B\u7121\u52B9\u306A\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002\u3053\u3053\u3067\u306F\u5B50\u8981\u7D20\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002
- cvc-complex-type.2.4.d.1 = cvc-complex-type.2.4.d: \u8981\u7D20''{0}''\u3067\u59CB\u307E\u308B\u7121\u52B9\u306A\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002\u3053\u3053\u3067\u306F\u5B50\u8981\u7D20''{1}''\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002
cvc-complex-type.2.4.e = cvc-complex-type.2.4.e: ''{0}''\u306F\u73FE\u5728\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u3067\u6700\u5927''{2}''\u56DE\u767A\u751F\u3059\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u3053\u306E\u5236\u9650\u3092\u8D85\u3048\u307E\u3057\u305F\u3002\u3053\u3053\u3067\u306F''{1}''\u306E\u3044\u305A\u308C\u304B\u304C\u5FC5\u8981\u3067\u3059\u3002
cvc-complex-type.2.4.f = cvc-complex-type.2.4.f: ''{0}''\u306F\u73FE\u5728\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u3067\u6700\u5927''{1}''\u56DE\u767A\u751F\u3059\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u3053\u306E\u5236\u9650\u3092\u8D85\u3048\u307E\u3057\u305F\u3002\u3053\u3053\u3067\u306F\u5B50\u8981\u7D20\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002
cvc-complex-type.2.4.g = cvc-complex-type.2.4.g: \u8981\u7D20''{0}''\u3067\u59CB\u307E\u308B\u7121\u52B9\u306A\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002''{1}''\u306F\u73FE\u5728\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u3067\u5C11\u306A\u304F\u3068\u3082''{2}''\u56DE\u767A\u751F\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u3053\u306E\u5236\u7D04\u3092\u6E80\u305F\u3059\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u304C\u3082\u30461\u3064\u5FC5\u8981\u3067\u3059\u3002
@@ -259,14 +258,14 @@
rcase-MapAndSum.2 = rcase-MapAndSum.2: \u30B0\u30EB\u30FC\u30D7\u306E\u51FA\u73FE\u7BC4\u56F2({0},{1})\u304C\u30D9\u30FC\u30B9\u30FB\u30B0\u30EB\u30FC\u30D7\u306E\u51FA\u73FE\u7BC4\u56F2({2},{3})\u306E\u6709\u52B9\u306A\u5236\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NameAndTypeOK.1 = rcase-NameAndTypeOK.1: \u8981\u7D20\u306B\u7570\u306A\u308B\u540D\u524D\u3084\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9\u304C\u542B\u307E\u308C\u307E\u3059: \u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9''{1}''\u306E\u8981\u7D20''{0}''\u304A\u3088\u3073\u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9''{3}''\u306E\u8981\u7D20''{2}''\u3067\u3059\u3002
rcase-NameAndTypeOK.2 = rcase-NameAndTypeOK.2: '{'term'}'\u304C\u8981\u7D20\u5BA3\u8A00''{0}''\u3067\u3042\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u30A8\u30E9\u30FC\u3002\u8981\u7D20\u5BA3\u8A00\u306E'{'nillable'}'\u306Ftrue\u3067\u3059\u304C\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306B\u306F'{'nillable'}'\u304Cfalse\u306E\u8981\u7D20\u5BA3\u8A00\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002
- rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: '{'term'}'\u304C\u8981\u7D20\u5BA3\u8A00''{0}''\u3067\u3042\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u30A8\u30E9\u30FC\u3002\u51FA\u73FE\u7BC4\u56F2({1},{2})\u306F\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u7BC4\u56F2({3},{4}\u306E\u6709\u52B9\u306A\u5236\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
+ rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: '{'term'}'\u304C\u8981\u7D20\u5BA3\u8A00''{0}''\u3067\u3042\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u30A8\u30E9\u30FC\u3002\u51FA\u73FE\u7BC4\u56F2({1},{2})\u306F\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u7BC4\u56F2({3},{4})\u306E\u6709\u52B9\u306A\u5236\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NameAndTypeOK.4.a = rcase-NameAndTypeOK.4.a: \u8981\u7D20''{0}''\u306F\u56FA\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u304C\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u8981\u7D20\u306F\u5024''{1}''\u3067\u56FA\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002
rcase-NameAndTypeOK.4.b = rcase-NameAndTypeOK.4.b: \u8981\u7D20''{0}''\u306F\u5024''{1}''\u3067\u56FA\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u8981\u7D20\u306F\u5024''{2}''\u3067\u56FA\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002
rcase-NameAndTypeOK.5 = rcase-NameAndTypeOK.5: \u8981\u7D20''{0}''\u306E\u30A2\u30A4\u30C7\u30F3\u30C6\u30A3\u30C6\u30A3\u5236\u7D04\u304C\u30D9\u30FC\u30B9\u306E\u30A2\u30A4\u30C7\u30F3\u30C6\u30A3\u30C6\u30A3\u5236\u7D04\u306E\u30B5\u30D6\u30BB\u30C3\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NameAndTypeOK.6 = rcase-NameAndTypeOK.6: \u8981\u7D20''{0}''\u306Edisallowed substitutions\u306F\u30D9\u30FC\u30B9\u306Edisallowed substitutions\u306E\u30B9\u30FC\u30D1\u30FC\u30BB\u30C3\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NameAndTypeOK.7 = rcase-NameAndTypeOK.7: \u8981\u7D20''{0}''\u306E\u30BF\u30A4\u30D7''{1}''\u306F\u3001\u30D9\u30FC\u30B9\u8981\u7D20\u306E\u30BF\u30A4\u30D7''{2}''\u304B\u3089\u5C0E\u51FA\u3055\u308C\u305F\u3082\u306E\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NSCompat.1 = rcase-NSCompat.1: \u8981\u7D20''{0}''\u306B\u3001\u30D9\u30FC\u30B9\u306E\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u3067\u8A31\u53EF\u3055\u308C\u3066\u3044\u306A\u3044\u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9''{1}''\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002
- rcase-NSCompat.2 = rcase-NSCompat.2: '{'term'}'\u304C\u8981\u7D20\u5BA3\u8A00''{0}''\u3067\u3042\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u30A8\u30E9\u30FC\u3002\u51FA\u73FE\u7BC4\u56F2({1},{2})\u306F\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u7BC4\u56F2({3},{4}\u306E\u6709\u52B9\u306A\u5236\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
+ rcase-NSCompat.2 = rcase-NSCompat.2: '{'term'}'\u304C\u8981\u7D20\u5BA3\u8A00''{0}''\u3067\u3042\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u30A8\u30E9\u30FC\u3002\u51FA\u73FE\u7BC4\u56F2({1},{2})\u306F\u3001\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u306E\u5BFE\u5FDC\u3059\u308B\u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u306E\u7BC4\u56F2({3},{4})\u306E\u6709\u52B9\u306A\u5236\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NSRecurseCheckCardinality.1 = rcase-NSRecurseCheckCardinality.1: \u30D1\u30FC\u30C6\u30A3\u30AF\u30EB\u9593\u306B\u5B8C\u5168\u306A\u6A5F\u80FD\u30DE\u30C3\u30D4\u30F3\u30B0\u304C\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NSRecurseCheckCardinality.2 = rcase-NSRecurseCheckCardinality.2: \u30B0\u30EB\u30FC\u30D7\u306E\u51FA\u73FE\u7BC4\u56F2({0},{1})\u304C\u30D9\u30FC\u30B9\u306E\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u306E\u7BC4\u56F2({2},{3})\u306E\u6709\u52B9\u306A\u5236\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
rcase-NSSubset.1 = rcase-NSSubset.1: \u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u304C\u3001\u30D9\u30FC\u30B9\u306E\u5BFE\u5FDC\u3059\u308B\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u306E\u30B5\u30D6\u30BB\u30C3\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
@@ -311,15 +310,15 @@
EmptyTargetNamespace = EmptyTargetNamespace: \u30B9\u30AD\u30FC\u30DE\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8''{0}''\u3067\u306F\u3001''targetNamespace''\u5C5E\u6027\u306E\u5024\u3092\u7A7A\u306E\u6587\u5B57\u5217\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002
FacetValueFromBase = FacetValueFromBase: \u30BF\u30A4\u30D7''{0}''\u306E\u5BA3\u8A00\u3067\u306F\u3001\u30D5\u30A1\u30BB\u30C3\u30C8''{2}''\u306E\u5024''{1}''\u306F\u30D9\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7''{3}''\u306E\u5024\u7A7A\u9593\u304B\u3089\u306E\u3082\u306E\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
FixedFacetValue = FixedFacetValue: {3}\u306E\u5B9A\u7FA9\u3067\u306F\u30D5\u30A1\u30BB\u30C3\u30C8''{0}''\u306E\u5024''{1}''\u306F\u7121\u52B9\u3067\u3059\u3002\u3053\u308C\u306F\u3001''{0}''\u306E\u5024\u304C\u7956\u5148\u30BF\u30A4\u30D7\u306E\u3044\u305A\u308C\u304B\u3067''{2}''\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u304A\u308A\u3001'{'fixed'}' = true\u3067\u3042\u308B\u305F\u3081\u3067\u3059\u3002
- InvalidRegex = InvalidRegex: pattern\u306E\u5024''{0}''\u306F\u7121\u52B9\u306A\u6B63\u898F\u8868\u73FE\u3067\u3059\u3002\u5217''{2}''\u3067''{1}''\u30A8\u30E9\u30FC\u304C\u5831\u544A\u3055\u308C\u307E\u3057\u305F\u3002
- MaxOccurLimit = \u73FE\u5728\u306E\u30D1\u30FC\u30B5\u30FC\u306E\u69CB\u6210\u3067\u306F\u3001maxOccurs\u5C5E\u6027\u306B\u5024{0}\u3088\u308A\u5927\u304D\u3044\u5024\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002
+ InvalidRegex = InvalidRegex: pattern\u306E\u5024''{0}''\u306F\u7121\u52B9\u306A\u6B63\u898F\u8868\u73FE\u3067\u3059\u3002\u5831\u544A\u3055\u308C\u305F\u30A8\u30E9\u30FC: ''{1}''\u3002
+ MaxOccurLimit = \u30D1\u30FC\u30B5\u30FC\u306E\u73FE\u5728\u306E\u69CB\u6210\u3067\u306F\u3001{0}\u500B\u3092\u8D85\u3048\u308B\u30CE\u30FC\u30C9\u3092\u542B\u3081\u308B\u305F\u3081\u306B\u8907\u5408\u30BF\u30A4\u30D7\u306E\u30B3\u30F3\u30C6\u30F3\u30C4\u30FB\u30E2\u30C7\u30EB\u3092\u62E1\u5F35\u3059\u308B\u3053\u3068\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\u3002
PublicSystemOnNotation = PublicSystemOnNotation: \u8981\u7D20''notation''\u306B\u306F''public''\u304A\u3088\u3073''system''\u306E\u5C11\u306A\u304F\u3068\u30821\u3064\u304C\u5FC5\u8981\u3067\u3059\u3002
SchemaLocation = SchemaLocation: schemaLocation\u306E\u5024''{0}''\u306B\u306F\u5076\u6570\u500B\u306EURI\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
TargetNamespace.1 = TargetNamespace.1: \u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9''{0}''\u304C\u5FC5\u8981\u3067\u3059\u304C\u3001\u30B9\u30AD\u30FC\u30DE\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9\u306F''{1}''\u3067\u3059\u3002
TargetNamespace.2 = TargetNamespace.2: \u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9\u306F\u5FC5\u8981\u3042\u308A\u307E\u305B\u3093\u304C\u3001\u30B9\u30AD\u30FC\u30DE\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306B''{1}''\u306E\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002
UndeclaredEntity = UndeclaredEntity: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3''{0}''\u304C\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
UndeclaredPrefix = UndeclaredPrefix: ''{0}''\u3092QName\u3068\u3057\u3066\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093\u3002\u63A5\u982D\u8F9E''{1}''\u304C\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
-
+ FacetsContradict = FacetsContradict: simpleType\u5B9A\u7FA9''{2}''\u3067\u306F\u3001\u5217\u6319\u5024''{0}''\u304C''{1}''\u30D5\u30A1\u30BB\u30C3\u30C8\u306E\u5024\u3068\u77DB\u76FE\u3057\u307E\u3059\u3002
# JAXP 1.2 schema source property errors
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,6 @@
cvc-complex-type.2.4.b = cvc-complex-type.2.4.b: \u5143\u7D20 ''{0}'' \u7684\u5185\u5BB9\u4E0D\u5B8C\u6574\u3002\u5E94\u4E3A ''{1}'' \u4E4B\u4E00\u3002
cvc-complex-type.2.4.c = cvc-complex-type.2.4.c: \u901A\u914D\u7B26\u7684\u5339\u914D\u5F88\u5168\u9762, \u4F46\u65E0\u6CD5\u627E\u5230\u5143\u7D20 ''{0}'' \u7684\u58F0\u660E\u3002
cvc-complex-type.2.4.d = cvc-complex-type.2.4.d: \u53D1\u73B0\u4E86\u4EE5\u5143\u7D20 ''{0}'' \u5F00\u5934\u7684\u65E0\u6548\u5185\u5BB9\u3002\u6B64\u5904\u4E0D\u5E94\u542B\u6709\u5B50\u5143\u7D20\u3002
- cvc-complex-type.2.4.d.1 = cvc-complex-type.2.4.d: \u53D1\u73B0\u4E86\u4EE5\u5143\u7D20 ''{0}'' \u5F00\u5934\u7684\u65E0\u6548\u5185\u5BB9\u3002\u6B64\u5904\u4E0D\u5E94\u542B\u6709\u5B50\u5143\u7D20 ''{1}''\u3002
cvc-complex-type.2.4.e = cvc-complex-type.2.4.e: ''{0}'' \u5728\u5F53\u524D\u5E8F\u5217\u4E2D\u6700\u591A\u53EF\u4EE5\u51FA\u73B0 ''{2}'' \u6B21\u3002\u5DF2\u8D85\u8FC7\u6B64\u9650\u5236\u3002\u6B64\u5904\u9884\u671F\u4E3A ''{1}'' \u4E4B\u4E00\u3002
cvc-complex-type.2.4.f = cvc-complex-type.2.4.f: ''{0}'' \u5728\u5F53\u524D\u5E8F\u5217\u4E2D\u6700\u591A\u53EF\u4EE5\u51FA\u73B0 ''{1}'' \u6B21\u3002\u5DF2\u8D85\u8FC7\u6B64\u9650\u5236\u3002\u6B64\u5904\u9884\u671F\u6CA1\u6709\u5B50\u5143\u7D20\u3002
cvc-complex-type.2.4.g = cvc-complex-type.2.4.g: \u53D1\u73B0\u4E86\u4EE5\u5143\u7D20 ''{0}'' \u5F00\u5934\u7684\u65E0\u6548\u5185\u5BB9\u3002''{1}'' \u9884\u671F\u5728\u5F53\u524D\u5E8F\u5217\u4E2D\u6700\u5C11\u51FA\u73B0 ''{2}'' \u6B21\u3002\u53E6\u5916\u4E00\u4E2A\u5B9E\u4F8B\u5FC5\u987B\u6EE1\u8DB3\u6B64\u7EA6\u675F\u6761\u4EF6\u3002
@@ -259,14 +258,14 @@
rcase-MapAndSum.2 = rcase-MapAndSum.2: \u7EC4\u7684\u53D1\u751F\u8303\u56F4 ({0},{1}) \u4E0D\u5728\u57FA\u7EC4\u7684\u53D1\u751F\u8303\u56F4 ({2},{3}) \u7684\u6709\u6548\u9650\u5236\u4E4B\u5185\u3002
rcase-NameAndTypeOK.1 = rcase-NameAndTypeOK.1: \u5143\u7D20\u7684\u540D\u79F0\u548C\u76EE\u6807\u540D\u79F0\u7A7A\u95F4\u4E0D\u76F8\u540C: \u540D\u79F0\u7A7A\u95F4 ''{1}'' \u4E2D\u7684\u5143\u7D20\u4E3A ''{0}'', \u540D\u79F0\u7A7A\u95F4 ''{3}'' \u4E2D\u7684\u5143\u7D20\u4E3A ''{2}''\u3002
rcase-NameAndTypeOK.2 = rcase-NameAndTypeOK.2: \u5176 '{'term'}' \u4E3A\u5143\u7D20\u58F0\u660E ''{0}'' \u7684\u7C92\u5B50\u9519\u8BEF\u3002\u5143\u7D20\u58F0\u660E\u7684 '{'nillable'}' \u4E3A\u201C\u771F\u201D, \u4F46\u57FA\u7C7B\u578B\u4E2D\u5BF9\u5E94\u7684\u7C92\u5B50\u5177\u6709 '{'nillable'}' \u4E3A\u201C\u5047\u201D\u7684\u5143\u7D20\u58F0\u660E\u3002
- rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: \u5176 '{'term'}' \u4E3A\u5143\u7D20\u58F0\u660E ''{0}'' \u7684\u7C92\u5B50\u9519\u8BEF\u3002\u8BE5\u7C92\u5B50\u7684\u53D1\u751F\u8303\u56F4 ({1},{2}) \u4E0D\u5728\u57FA\u7C7B\u578B\u4E2D\u5BF9\u5E94\u7C92\u5B50\u7684\u8303\u56F4 ({3},{4}) \u7684\u6709\u6548\u9650\u5236\u4E4B\u5185\u3002
+ rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3\uFF1A\u5176 '{'term'}' \u4E3A\u5143\u7D20\u58F0\u660E ''{0}'' \u7684\u7C92\u5B50\u9519\u8BEF\u3002\u8BE5\u7C92\u5B50\u7684\u53D1\u751F\u8303\u56F4 ({1},{2}) \u4E0D\u5728\u57FA\u7C7B\u578B\u4E2D\u5BF9\u5E94\u7C92\u5B50\u7684\u8303\u56F4 ({3},{4}) \u7684\u6709\u6548\u9650\u5236\u4E4B\u5185\u3002
rcase-NameAndTypeOK.4.a = rcase-NameAndTypeOK.4.a: \u5143\u7D20 ''{0}'' \u4E0D\u662F\u56FA\u5B9A\u7684, \u4F46\u57FA\u7C7B\u578B\u4E2D\u7684\u5BF9\u5E94\u5143\u7D20\u662F\u56FA\u5B9A\u7684, \u4E14\u503C\u4E3A ''{1}''\u3002
rcase-NameAndTypeOK.4.b = rcase-NameAndTypeOK.4.b: \u5143\u7D20 ''{0}'' \u662F\u56FA\u5B9A\u7684, \u4E14\u503C\u4E3A ''{1}'', \u4F46\u57FA\u7C7B\u578B\u4E2D\u7684\u5BF9\u5E94\u5143\u7D20\u662F\u56FA\u5B9A\u7684, \u4E14\u503C\u4E3A ''{2}''\u3002
rcase-NameAndTypeOK.5 = rcase-NameAndTypeOK.5: \u5143\u7D20 ''{0}'' \u7684\u8EAB\u4EFD\u7EA6\u675F\u6761\u4EF6\u4E0D\u662F\u57FA\u7C7B\u578B\u4E2D\u90A3\u4E9B\u8EAB\u4EFD\u7EA6\u675F\u6761\u4EF6\u7684\u5B50\u96C6\u3002
rcase-NameAndTypeOK.6 = rcase-NameAndTypeOK.6: \u5143\u7D20 ''{0}'' \u7684\u4E0D\u63A5\u53D7\u66FF\u4EE3\u4E0D\u662F\u57FA\u5143\u7D20\u4E2D\u4E0D\u63A5\u53D7\u66FF\u4EE3\u7684\u8D85\u96C6\u3002
rcase-NameAndTypeOK.7 = rcase-NameAndTypeOK.7: \u5143\u7D20 ''{0}'' \u7684\u7C7B\u578B ''{1}'' \u4E0D\u662F\u4ECE\u57FA\u5143\u7D20\u7684\u7C7B\u578B ''{2}'' \u6D3E\u751F\u7684\u3002
rcase-NSCompat.1 = rcase-NSCompat.1: \u5143\u7D20 ''{0}'' \u5177\u6709\u540D\u79F0\u7A7A\u95F4 ''{1}'', \u5728\u57FA\u5143\u7D20\u4E2D, \u901A\u914D\u7B26\u4E0D\u5141\u8BB8\u5177\u6709\u6B64\u540D\u79F0\u7A7A\u95F4\u3002
- rcase-NSCompat.2 = rcase-NSCompat.2: \u5176 '{'term'}' \u4E3A\u5143\u7D20\u58F0\u660E ''{0}'' \u7684\u7C92\u5B50\u9519\u8BEF\u3002\u8BE5\u7C92\u5B50\u7684\u53D1\u751F\u8303\u56F4 ({1},{2}) \u4E0D\u5728\u57FA\u7C7B\u578B\u4E2D\u5BF9\u5E94\u7C92\u5B50\u7684\u8303\u56F4 ({3},{4}) \u7684\u6709\u6548\u9650\u5236\u4E4B\u5185\u3002
+ rcase-NSCompat.2 = rcase-NSCompat.2\uFF1A\u5176 '{'term'}' \u4E3A\u5143\u7D20\u58F0\u660E ''{0}'' \u7684\u7C92\u5B50\u9519\u8BEF\u3002\u8BE5\u7C92\u5B50\u7684\u53D1\u751F\u8303\u56F4 ({1},{2}) \u4E0D\u5728\u57FA\u7C7B\u578B\u4E2D\u5BF9\u5E94\u7C92\u5B50\u7684\u8303\u56F4 ({3},{4}) \u7684\u6709\u6548\u9650\u5236\u4E4B\u5185\u3002
rcase-NSRecurseCheckCardinality.1 = rcase-NSRecurseCheckCardinality.1: \u7C92\u5B50\u4E4B\u95F4\u6CA1\u6709\u5B8C\u6574\u7684\u529F\u80FD\u6620\u5C04\u3002
rcase-NSRecurseCheckCardinality.2 = rcase-NSRecurseCheckCardinality.2: \u7EC4\u7684\u53D1\u751F\u8303\u56F4 ({0},{1}) \u4E0D\u5728\u57FA\u672C\u901A\u914D\u7B26\u8303\u56F4 ({2},{3}) \u7684\u6709\u6548\u9650\u5236\u4E4B\u5185\u3002
rcase-NSSubset.1 = rcase-NSSubset.1: \u901A\u914D\u7B26\u4E0D\u662F\u57FA\u672C\u901A\u914D\u7B26\u4E2D\u5BF9\u5E94\u901A\u914D\u7B26\u7684\u5B50\u96C6\u3002
@@ -311,15 +310,15 @@
EmptyTargetNamespace = EmptyTargetNamespace: \u5728\u65B9\u6848\u6587\u6863 ''{0}'' \u4E2D, ''targetNamespace'' \u5C5E\u6027\u7684\u503C\u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32\u3002
FacetValueFromBase = FacetValueFromBase: \u5728\u7C7B\u578B ''{0}'' \u7684\u58F0\u660E\u4E2D, \u9762 ''{2}'' \u7684\u503C ''{1}'' \u5FC5\u987B\u6765\u81EA\u57FA\u7C7B\u578B\u7684\u503C\u7A7A\u95F4 ''{3}''\u3002
FixedFacetValue = FixedFacetValue: \u5728 {3} \u7684\u5B9A\u4E49\u4E2D, \u9762 ''{0}'' \u7684\u503C ''{1}'' \u65E0\u6548, \u56E0\u4E3A ''{0}'' \u7684\u503C\u5DF2\u5728\u539F\u7EA7\u7C7B\u578B\u4E4B\u4E00\u4E2D\u8BBE\u7F6E\u4E3A ''{2}'', \u5E76\u4E14 '{'fixed'}' = true\u3002
- InvalidRegex = InvalidRegex: \u6A21\u5F0F\u503C ''{0}'' \u4E0D\u662F\u6709\u6548\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u3002\u5217 ''{2}'' \u4E0A\u62A5\u544A\u7684\u9519\u8BEF\u4E3A: ''{1}''\u3002
- MaxOccurLimit = \u89E3\u6790\u5668\u7684\u5F53\u524D\u914D\u7F6E\u4E0D\u5141\u8BB8\u5C06 maxOccurs \u5C5E\u6027\u503C\u8BBE\u7F6E\u4E3A\u5927\u4E8E\u503C {0}\u3002
+ InvalidRegex = InvalidRegex\uFF1A\u6A21\u5F0F\u503C ''{0}'' \u4E0D\u662F\u6709\u6548\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u3002\u62A5\u544A\u7684\u9519\u8BEF\u4E3A\uFF1A''{1}''\u3002
+ MaxOccurLimit = \u89E3\u6790\u5668\u7684\u5F53\u524D\u914D\u7F6E\u4E0D\u5141\u8BB8\u5C06\u590D\u6742\u7C7B\u578B\u7684\u5185\u5BB9\u6A21\u578B\u6269\u5C55\u5230\u5305\u542B {0} \u4E2A\u4EE5\u4E0A\u8282\u70B9\u3002
PublicSystemOnNotation = PublicSystemOnNotation: \u5143\u7D20 ''notation'' \u4E2D\u5FC5\u987B\u81F3\u5C11\u51FA\u73B0 ''public'' \u548C ''system'' \u4E2D\u7684\u4E00\u4E2A\u3002
SchemaLocation = SchemaLocation: schemaLocation \u503C ''{0}'' \u5FC5\u987B\u5177\u6709\u5076\u6570\u4E2A URI\u3002
TargetNamespace.1 = TargetNamespace.1: \u5E94\u4E3A\u540D\u79F0\u7A7A\u95F4 ''{0}'', \u4F46\u65B9\u6848\u6587\u6863\u7684\u76EE\u6807\u540D\u79F0\u7A7A\u95F4\u4E3A ''{1}''\u3002
TargetNamespace.2 = TargetNamespace.2: \u4E0D\u9700\u8981\u540D\u79F0\u7A7A\u95F4, \u4F46\u6B64\u65B9\u6848\u6587\u6863\u7684\u76EE\u6807\u540D\u79F0\u7A7A\u95F4\u4E3A ''{1}''\u3002
UndeclaredEntity = UndeclaredEntity: \u672A\u58F0\u660E\u5B9E\u4F53 ''{0}''\u3002
UndeclaredPrefix = UndeclaredPrefix: \u65E0\u6CD5\u5C06 ''{0}'' \u89E3\u6790\u4E3A\u9650\u5B9A\u540D: \u672A\u58F0\u660E\u524D\u7F00 ''{1}''\u3002
-
+ FacetsContradict = FacetsContradict\uFF1A\u5BF9\u4E8E simpleType \u5B9A\u4E49 ''{2}''\uFF0C\u679A\u4E3E\u503C ''{0}'' \u4E0E ''{1}'' \u9762\u7684\u503C\u51B2\u7A81\u3002
# JAXP 1.2 schema source property errors
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/XPathMatcher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/identity/XPathMatcher.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -37,6 +37,7 @@
* @xerces.internal
*
* @author Andy Clark, IBM
+ * @LastModified: July 2019
*
*/
public class XPathMatcher {
@@ -88,25 +89,25 @@
//
/** XPath location path. */
- private XPath.LocationPath[] fLocationPaths;
+ private final XPath.LocationPath[] fLocationPaths;
/** True if XPath has been matched. */
- private int[] fMatched;
+ private final int[] fMatched;
/** The matching string. */
protected Object fMatchedString;
/** Integer stack of step indexes. */
- private IntStack[] fStepIndexes;
+ private final IntStack[] fStepIndexes;
/** Current step. */
- private int[] fCurrentStep;
+ private final int[] fCurrentStep;
/**
* No match depth. The value of this field will be zero while
* matching is successful for the given xpath expression.
*/
- private int [] fNoMatchDepth;
+ private final int [] fNoMatchDepth;
final QName fQName = new QName();
@@ -207,7 +208,7 @@
*
* @throws SAXException Thrown by handler to signal an error.
*/
- public void startElement(QName element, XMLAttributes attributes){
+ public void startElement(QName element, XMLAttributes attributes) {
if (DEBUG_METHODS2) {
System.out.println(toString()+"#startElement("+
"element={"+element+"},"+
@@ -215,7 +216,7 @@
")");
}
- for(int i = 0; i < fLocationPaths.length; i++) {
+ for (int i = 0; i < fLocationPaths.length; i++) {
// push context
int startStep = fCurrentStep[i];
fStepIndexes[i].push(startStep);
@@ -284,18 +285,16 @@
if (DEBUG_MATCH) {
System.out.println(toString()+" [CHILD] before");
}
- if (nodeTest.type == XPath.NodeTest.QNAME) {
- if (!nodeTest.name.equals(element)) {
- if(fCurrentStep[i] > descendantStep) {
- fCurrentStep[i] = descendantStep;
- continue;
- }
- fNoMatchDepth[i]++;
- if (DEBUG_MATCH) {
- System.out.println(toString()+" [CHILD] after NO MATCH");
- }
+ if (!matches(nodeTest, element)) {
+ if (fCurrentStep[i] > descendantStep) {
+ fCurrentStep[i] = descendantStep;
continue;
}
+ fNoMatchDepth[i]++;
+ if (DEBUG_MATCH) {
+ System.out.println(toString()+" [CHILD] after NO MATCH");
+ }
+ continue;
}
fCurrentStep[i]++;
if (DEBUG_MATCH) {
@@ -303,10 +302,11 @@
}
}
if (fCurrentStep[i] == steps.length) {
- if(sawDescendant) {
+ if (sawDescendant) {
fCurrentStep[i] = descendantStep;
fMatched[i] = MATCHED_DESCENDANT;
- } else {
+ }
+ else {
fMatched[i] = MATCHED;
}
continue;
@@ -324,8 +324,7 @@
for (int aIndex = 0; aIndex < attrCount; aIndex++) {
attributes.getName(aIndex, fQName);
- if (nodeTest.type != XPath.NodeTest.QNAME ||
- nodeTest.name.equals(fQName)) {
+ if (matches(nodeTest, fQName)) {
fCurrentStep[i]++;
if (fCurrentStep[i] == steps.length) {
fMatched[i] = MATCHED_ATTRIBUTE;
@@ -384,7 +383,7 @@
"element={"+element+"},"+
")");
}
- for(int i = 0; i<fLocationPaths.length; i++) {
+ for (int i = 0; i < fLocationPaths.length; i++) {
// go back a step
fCurrentStep[i] = fStepIndexes[i].pop();
@@ -395,10 +394,13 @@
// signal match, if appropriate
else {
- int j=0;
- for(; j<i && ((fMatched[j] & MATCHED) != MATCHED); j++);
- if ((j<i) || (fMatched[j] == 0) ||
- ((fMatched[j] & MATCHED_ATTRIBUTE) == MATCHED_ATTRIBUTE)) {
+ int j = 0;
+ for(; j < i && ((fMatched[j] & MATCHED) != MATCHED); j++);
+ if ((j < i) || (fMatched[j] == 0)) {
+ continue;
+ }
+ if ((fMatched[j] & MATCHED_ATTRIBUTE) == MATCHED_ATTRIBUTE) {
+ fMatched[i] = 0;
continue;
}
// only certain kinds of matchers actually
@@ -476,6 +478,18 @@
return str.toString();
} // normalize(String):String
+ /** Returns true if the given QName matches the node test. **/
+ private static boolean matches(XPath.NodeTest nodeTest, QName value) {
+ if (nodeTest.type == XPath.NodeTest.QNAME) {
+ return nodeTest.name.equals(value);
+ }
+ if (nodeTest.type == XPath.NodeTest.NAMESPACE) {
+ return nodeTest.name.uri == value.uri;
+ }
+ // XPath.NodeTest.WILDCARD
+ return true;
+ } // matches(XPath.NodeTest,QName):boolean
+
//
// MAIN
//
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,7 +40,7 @@
* because it is used from another package.
*
* @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2019
*/
public final class ToHTMLStream extends ToStream
{
@@ -719,7 +719,7 @@
public final void endDocument() throws org.xml.sax.SAXException
{
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
flushPending();
if (m_doIndent && !m_isprevtext)
@@ -782,7 +782,7 @@
if (m_doIndent) {
// will add extra one if having namespace but no matter
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
ElemContext elemContext = m_elemContext;
@@ -923,7 +923,7 @@
throws org.xml.sax.SAXException
{
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
// deal with any pending issues
if (m_cdataTagOpen)
@@ -1645,7 +1645,7 @@
{
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
// Process any pending starDocument and startElement first.
flushPending();
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -51,7 +51,7 @@
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2019
*/
abstract public class ToStream extends SerializerBase {
@@ -1231,7 +1231,7 @@
m_elemContext.m_startTagOpen = false;
}
- if (!m_cdataTagOpen && shouldIndent())
+ if (!m_cdataTagOpen && shouldIndentForText())
indent();
boolean writeCDataBrackets =
@@ -1270,6 +1270,7 @@
closeCDATA();
}
+ m_isprevtext = true;
// time to fire off CDATA event
if (m_tracer != null)
super.fireCDATAEvent(ch, old_start, length);
@@ -1536,11 +1537,13 @@
}
/**
- * Used to flush the buffered characters when indentation is on, this method
- * will be called when the next node is traversed.
+ * Flushes the buffered characters when indentation is on. This method
+ * is called before the next node is traversed.
*
+ * @param isText indicates whether the node to be traversed is text
+ * @throws org.xml.sax.SAXException
*/
- final protected void flushCharactersBuffer() throws SAXException {
+ final protected void flushCharactersBuffer(boolean isText) throws SAXException {
try {
if (shouldFormatOutput() && m_charactersBuffer.isAnyCharactersBuffered()) {
if (m_elemContext.m_isCdataSection) {
@@ -1553,7 +1556,9 @@
return;
}
- m_childNodeNum++;
+ if (!isText) {
+ m_childNodeNum++;
+ }
boolean skipBeginningNewlines = false;
if (shouldIndentForText()) {
indent();
@@ -1846,7 +1851,7 @@
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
if (m_needToCallStartDocument)
@@ -2117,7 +2122,7 @@
return;
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
// namespaces declared at the current depth are no longer valid
// so get rid of them
@@ -2309,7 +2314,7 @@
return;
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
if (m_elemContext.m_startTagOpen)
{
@@ -2491,8 +2496,7 @@
public void startCDATA() throws org.xml.sax.SAXException
{
if (m_doIndent) {
- m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(true);
}
m_cdataStartCalled = true;
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,6 +40,7 @@
* be viewed as internal or package private, this is not an API.
*
* @xsl.usage internal
+ * @LastModified: July 2019
*/
public final class ToXMLStream extends ToStream
{
@@ -200,7 +201,7 @@
public void endDocument() throws org.xml.sax.SAXException
{
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
flushPending();
if (m_doIndent && !m_isprevtext)
@@ -267,7 +268,7 @@
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
flushPending();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/jdk/xml/internal/ErrorHandlerProxy.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 jdk.xml.internal;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Implements an ErrorHandler that simply passes on the Exception.
+ */
+public class ErrorHandlerProxy implements ErrorHandler {
+
+ @Override
+ public void warning(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+
+ @Override
+ public void error(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+
+ @Override
+ public void fatalError(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+}
--- a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, 2018, SAP SE. All rights reserved.
+ * Copyright (c) 2015, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -254,8 +254,12 @@
return VirtualMachineImpl.read(s, bs, off, len);
}
- public void close() throws IOException {
- VirtualMachineImpl.close(s);
+ public synchronized void close() throws IOException {
+ if (s != -1) {
+ int toClose = s;
+ s = -1;
+ VirtualMachineImpl.close(toClose);
+ }
}
}
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -260,12 +260,11 @@
return VirtualMachineImpl.read(s, bs, off, len);
}
- public void close() throws IOException {
- synchronized (this) {
- if (s != -1) {
- VirtualMachineImpl.close(s);
- s = -1;
- }
+ public synchronized void close() throws IOException {
+ if (s != -1) {
+ int toClose = s;
+ s = -1;
+ VirtualMachineImpl.close(toClose);
}
}
}
--- a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -256,8 +256,12 @@
return VirtualMachineImpl.read(s, bs, off, len);
}
- public void close() throws IOException {
- VirtualMachineImpl.close(s);
+ public synchronized void close() throws IOException {
+ if (s != -1) {
+ int toClose = s;
+ s = -1;
+ VirtualMachineImpl.close(toClose);
+ }
}
}
--- a/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -204,8 +204,12 @@
return VirtualMachineImpl.read(s, bs, off, len);
}
- public void close() throws IOException {
- VirtualMachineImpl.close(s);
+ public synchronized void close() throws IOException {
+ if (s != -1) {
+ int toClose = s;
+ s = -1;
+ VirtualMachineImpl.close(toClose);
+ }
}
}
--- a/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -169,10 +169,11 @@
return VirtualMachineImpl.readPipe(hPipe, bs, off, len);
}
- public void close() throws IOException {
+ public synchronized void close() throws IOException {
if (hPipe != -1) {
- VirtualMachineImpl.closePipe(hPipe);
+ long toClose = hPipe;
hPipe = -1;
+ VirtualMachineImpl.closePipe(toClose);
}
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -63,8 +63,9 @@
dc.tag.a.within.a = <a>\u306B\u5C55\u958B\u3055\u308C\u308B<a>\u5185\u306E{0}\u30BF\u30B0
dc.tag.end.not.permitted = \u7121\u52B9\u306A\u7D42\u4E86\u30BF\u30B0: </{0}>
dc.tag.end.unexpected = \u4E88\u671F\u3057\u306A\u3044\u7D42\u4E86\u30BF\u30B0: </{0}>
-dc.tag.header.sequence.1 = \u30D8\u30C3\u30C0\u30FC\u306E\u6307\u5B9A\u9806\u5E8F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093: <{0}>
-dc.tag.header.sequence.2 = \u30D8\u30C3\u30C0\u30FC\u306E\u6307\u5B9A\u9806\u5E8F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093: <{0}>
+dc.tag.heading.sequence.1 = \u6697\u9ED9\u7684\u306A\u5148\u884C\u898B\u51FA\u3057: <H{1}>\u3068\u306E\u6BD4\u8F03\u3067\u3001\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u898B\u51FA\u3057: <{0}>\u306E\u9806\u5E8F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093
+dc.tag.heading.sequence.2 = \u524D\u306E\u898B\u51FA\u3057: <{1}>\u3068\u306E\u6BD4\u8F03\u3067\u3001\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u898B\u51FA\u3057: <{0}>\u306E\u9806\u5E8F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093
+dc.tag.heading.sequence.3 = \u6697\u9ED9\u7684\u306A\u5148\u884C\u898B\u51FA\u3057: <H{1}>\u3068\u306E\u6BD4\u8F03\u3067\u3001\u4E88\u671F\u3057\u306A\u3044\u898B\u51FA\u3057: <{0}>\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059
dc.tag.nested.not.allowed=\u30CD\u30B9\u30C8\u3057\u305F\u30BF\u30B0\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093: <{0}>
dc.tag.not.allowed.here = \u3053\u3053\u3067\u306F\u30BF\u30B0\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093: <{0}>
dc.tag.not.allowed = \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30FB\u30B3\u30E1\u30F3\u30C8\u3067\u4F7F\u7528\u3067\u304D\u306A\u3044\u8981\u7D20\u3067\u3059: <{0}>
--- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -63,8 +63,9 @@
dc.tag.a.within.a = {0} \u6807\u8BB0\uFF0C\u5176\u6269\u5C55\u5230 <a>\uFF0C\u4F4D\u4E8E <a> \u5185
dc.tag.end.not.permitted = \u65E0\u6548\u7684\u7ED3\u675F\u6807\u8BB0: </{0}>
dc.tag.end.unexpected = \u610F\u5916\u7684\u7ED3\u675F\u6807\u8BB0: </{0}>
-dc.tag.header.sequence.1 = \u4F7F\u7528\u7684\u6807\u9898\u8D85\u51FA\u5E8F\u5217: <{0}>
-dc.tag.header.sequence.2 = \u4F7F\u7528\u7684\u6807\u9898\u8D85\u51FA\u5E8F\u5217: <{0}>
+dc.tag.heading.sequence.1 = \u4F7F\u7528\u7684\u6807\u9898\u8D85\u51FA\u5E8F\u5217\uFF1A<{0}>\uFF08\u4E0E\u9690\u5F0F\u524D\u5BFC\u6807\u9898\u76F8\u6BD4\uFF1A<H{1}>\uFF09
+dc.tag.heading.sequence.2 = \u4F7F\u7528\u7684\u6807\u9898\u8D85\u51FA\u5E8F\u5217\uFF1A<{0}>\uFF08\u4E0E\u524D\u4E00\u4E2A\u6807\u9898\u76F8\u6BD4\uFF1A<{1}>\uFF09
+dc.tag.heading.sequence.3 = \u4F7F\u7528\u4E86\u610F\u5916\u7684\u6807\u9898\uFF1A<{0}>\uFF08\u4E0E\u9690\u5F0F\u524D\u5BFC\u6807\u9898\u76F8\u6BD4\uFF1A<H{1}>\uFF09
dc.tag.nested.not.allowed=\u4E0D\u5141\u8BB8\u4F7F\u7528\u5D4C\u5957\u6807\u8BB0: <{0}>
dc.tag.not.allowed.here = \u6B64\u5904\u4E0D\u5141\u8BB8\u4F7F\u7528\u6807\u8BB0: <{0}>
dc.tag.not.allowed = \u6587\u6863\u6CE8\u91CA\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u5143\u7D20: <{0}>
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Mon Jul 22 11:08:27 2019 +0530
@@ -28,13 +28,12 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.BreakIterator;
-import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
@@ -60,9 +59,8 @@
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.EndElementTree;
-import com.sun.source.doctree.StartElementTree;
import com.sun.source.tree.CatchTree;
+import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Scope;
import com.sun.source.tree.Tree;
@@ -71,13 +69,11 @@
import com.sun.source.util.DocTreeScanner;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
-import com.sun.source.util.SimpleDocTreeVisitor;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope.NamedImportScope;
import com.sun.tools.javac.code.Scope.StarImportScope;
import com.sun.tools.javac.code.Scope.WriteableScope;
-import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
@@ -94,11 +90,13 @@
import com.sun.tools.javac.code.Types.TypeRelation;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.MemberEnter;
import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.parser.DocCommentParser;
@@ -133,6 +131,7 @@
import com.sun.tools.javac.tree.TreeCopier;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
@@ -171,6 +170,7 @@
private Log log;
private MemberEnter memberEnter;
private Attr attr;
+ private Check chk;
private TreeMaker treeMaker;
private JavacElements elements;
private JavacTaskImpl javacTaskImpl;
@@ -218,6 +218,7 @@
private void init(Context context) {
modules = Modules.instance(context);
attr = Attr.instance(context);
+ chk = Check.instance(context);
enter = Enter.instance(context);
elements = JavacElements.instance(context);
log = Log.instance(context);
@@ -915,13 +916,13 @@
try {
Assert.check(method.body == tree);
method.body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf());
- env = attribStatToTree(method.body, env, copier.leafCopy);
+ env = attribStatToTree(method.body, env, copier.leafCopy, copier.copiedClasses);
} finally {
method.body = (JCBlock) tree;
}
} else {
JCBlock body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf());
- env = attribStatToTree(body, env, copier.leafCopy);
+ env = attribStatToTree(body, env, copier.leafCopy, copier.copiedClasses);
}
return env;
}
@@ -930,7 +931,7 @@
if (field != null && field.getInitializer() == tree) {
env = memberEnter.getInitEnv(field, env);
JCExpression expr = copier.copy((JCExpression)tree, (JCTree) path.getLeaf());
- env = attribExprToTree(expr, env, copier.leafCopy);
+ env = attribExprToTree(expr, env, copier.leafCopy, copier.copiedClasses);
return env;
}
}
@@ -938,24 +939,137 @@
return (field != null) ? memberEnter.getInitEnv(field, env) : env;
}
- private Env<AttrContext> attribStatToTree(JCTree stat, Env<AttrContext>env, JCTree tree) {
+ private Env<AttrContext> attribStatToTree(JCTree stat, Env<AttrContext>env,
+ JCTree tree, Map<JCClassDecl, JCClassDecl> copiedClasses) {
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
- return attr.attribStatToTree(stat, env, tree);
+ Env<AttrContext> result = attr.attribStatToTree(stat, env, tree);
+
+ enter.unenter(env.toplevel, stat);
+ fixLocalClassNames(copiedClasses, env);
+ return result;
} finally {
+ log.popDiagnosticHandler(diagHandler);
+ log.useSource(prev);
+ }
+ }
+
+ private Env<AttrContext> attribExprToTree(JCExpression expr, Env<AttrContext>env,
+ JCTree tree, Map<JCClassDecl, JCClassDecl> copiedClasses) {
+ JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+ Env<AttrContext> result = attr.attribExprToTree(expr, env, tree);
+
+ enter.unenter(env.toplevel, expr);
+ fixLocalClassNames(copiedClasses, env);
+ return result;
+ } finally {
+ log.popDiagnosticHandler(diagHandler);
log.useSource(prev);
}
}
- private Env<AttrContext> attribExprToTree(JCExpression expr, Env<AttrContext>env, JCTree tree) {
- JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
- try {
- return attr.attribExprToTree(expr, env, tree);
- } finally {
- log.useSource(prev);
+ /* Change the flatnames of the local and anonymous classes in the Scope to
+ * the names they would have if the whole file was attributed normally.
+ */
+ private void fixLocalClassNames(Map<JCClassDecl, JCClassDecl> copiedClasses,
+ Env<AttrContext> lastEnv) {
+ Map<JCClassDecl, Name> flatnameForClass = null;
+
+ for (Entry<JCClassDecl, JCClassDecl> e : copiedClasses.entrySet()) {
+ if (e.getKey().sym != null) {
+ Name origName;
+ if (e.getValue().sym != null) {
+ //if the source tree was already attributed, use the flatname
+ //from the source tree's Symbol:
+ origName = e.getValue().sym.flatname;
+ } else {
+ //otherwise, compute the flatnames (for source trees) as
+ //if the full source code would be attributed:
+ if (flatnameForClass == null) {
+ flatnameForClass = prepareFlatnameForClass(lastEnv);
+ }
+ origName = flatnameForClass.get(e.getValue());
+ }
+ if (origName != null) {
+ e.getKey().sym.flatname = origName;
+ }
+ }
}
}
+ /* This method computes and assigns flatnames to trees, as if they would be
+ * normally assigned during attribution of the full source code.
+ */
+ private Map<JCTree.JCClassDecl, Name> prepareFlatnameForClass(Env<AttrContext> env) {
+ Map<JCClassDecl, Name> flatNameForClass = new HashMap<>();
+ Symbol enclClass = env.enclClass.sym;
+
+ if (enclClass != null && (enclClass.flags_field & Flags.UNATTRIBUTED) != 0) {
+ ListBuffer<ClassSymbol> toClear = new ListBuffer<>();
+ new TreeScanner() {
+ Symbol owner;
+ boolean localContext;
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //compute the name (and ClassSymbol) which would be used
+ //for this class for full attribution
+ Symbol prevOwner = owner;
+ try {
+ ClassSymbol c;
+ if (tree.sym != null) {
+ //already entered:
+ c = tree.sym;
+ } else {
+ c = syms.defineClass(tree.name, owner);
+ if (owner.kind != TYP) {
+ //for local classes, assign the flatname
+ c.flatname = chk.localClassName(c);
+ chk.putCompiled(c);
+ toClear.add(c);
+ }
+ flatNameForClass.put(tree, c.flatname);
+ }
+ owner = c;
+ super.visitClassDef(tree);
+ } finally {
+ owner = prevOwner;
+ }
+ }
+
+ @Override
+ public void visitBlock(JCBlock tree) {
+ Symbol prevOwner = owner;
+ try {
+ owner = new MethodSymbol(0, names.empty, Type.noType, owner);
+ super.visitBlock(tree);
+ } finally {
+ owner = prevOwner;
+ }
+ }
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ Symbol prevOwner = owner;
+ try {
+ owner = new MethodSymbol(0, names.empty, Type.noType, owner);
+ super.visitVarDef(tree);
+ } finally {
+ owner = prevOwner;
+ }
+ }
+ }.scan(env.enclClass);
+ //revert changes done by the visitor:
+ toClear.stream().forEach(c -> {
+ chk.clearLocalClassNameIndexes(c);
+ chk.removeCompiled(c);
+ });
+ }
+
+ return flatNameForClass;
+ }
+
static JavaFileObject asJavaFileObject(FileObject fileObject) {
JavaFileObject jfo = null;
@@ -1065,6 +1179,7 @@
**/
protected static class Copier extends TreeCopier<JCTree> {
JCTree leafCopy = null;
+ private Map<JCClassDecl, JCClassDecl> copiedClasses = new HashMap<>();
protected Copier(TreeMaker M) {
super(M);
@@ -1077,6 +1192,14 @@
leafCopy = t2;
return t2;
}
+
+ @Override
+ public JCTree visitClass(ClassTree node, JCTree p) {
+ JCTree nue = super.visitClass(node, p);
+ copiedClasses.put((JCClassDecl) nue, (JCClassDecl) node);
+ return nue;
+ }
+
}
protected Copier createCopier(TreeMaker maker) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Jul 22 11:08:27 2019 +0530
@@ -407,7 +407,7 @@
* enclClass is the flat name of the enclosing class,
* classname is the simple name of the local class
*/
- Name localClassName(ClassSymbol c) {
+ public Name localClassName(ClassSymbol c) {
Name enclFlatname = c.owner.enclClass().flatname;
String enclFlatnameStr = enclFlatname.toString();
Pair<Name, Name> key = new Pair<>(enclFlatname, c.name);
@@ -422,7 +422,7 @@
}
}
- void clearLocalClassNameIndexes(ClassSymbol c) {
+ public void clearLocalClassNameIndexes(ClassSymbol c) {
if (c.owner != null && c.owner.kind != NIL) {
localClassNameIndexes.remove(new Pair<>(
c.owner.enclClass().flatname, c.name));
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Mon Jul 22 11:08:27 2019 +0530
@@ -41,7 +41,6 @@
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.GraphUtils.DependencyKind;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
-import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.Attr.ResultInfo;
import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
@@ -501,7 +500,7 @@
attr.attribTree(newTree, speculativeEnv, resultInfo);
return newTree;
} finally {
- new UnenterScanner(env.toplevel.modle).scan(newTree);
+ enter.unenter(env.toplevel, newTree);
log.popDiagnosticHandler(deferredDiagnosticHandler);
if (localCache != null) {
localCache.leave();
@@ -509,29 +508,6 @@
}
}
//where
-
- class UnenterScanner extends TreeScanner {
- private final ModuleSymbol msym;
-
- public UnenterScanner(ModuleSymbol msym) {
- this.msym = msym;
- }
-
- @Override
- public void visitClassDef(JCClassDecl tree) {
- ClassSymbol csym = tree.sym;
- //if something went wrong during method applicability check
- //it is possible that nested expressions inside argument expression
- //are left unchecked - in such cases there's nothing to clean up.
- if (csym == null) return;
- typeEnvs.remove(csym);
- chk.removeCompiled(csym);
- chk.clearLocalClassNameIndexes(csym);
- syms.removeClass(msym, csym.flatname);
- super.visitClassDef(tree);
- }
- }
-
static class DeferredAttrDiagHandler extends Log.DeferredDiagnosticHandler {
static class PosScanner extends TreeScanner {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Mon Jul 22 11:08:27 2019 +0530
@@ -610,4 +610,29 @@
public void newRound() {
typeEnvs.clear();
}
+
+ public void unenter(JCCompilationUnit topLevel, JCTree tree) {
+ new UnenterScanner(topLevel.modle).scan(tree);
+ }
+ class UnenterScanner extends TreeScanner {
+ private final ModuleSymbol msym;
+
+ public UnenterScanner(ModuleSymbol msym) {
+ this.msym = msym;
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ ClassSymbol csym = tree.sym;
+ //if something went wrong during method applicability check
+ //it is possible that nested expressions inside argument expression
+ //are left unchecked - in such cases there's nothing to clean up.
+ if (csym == null) return;
+ typeEnvs.remove(csym);
+ chk.removeCompiled(csym);
+ chk.clearLocalClassNameIndexes(csym);
+ syms.removeClass(msym, csym.flatname);
+ super.visitClassDef(tree);
+ }
+ }
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Jul 22 11:08:27 2019 +0530
@@ -1709,8 +1709,9 @@
}
break;
case VARDEF:
- if (((JCVariableDecl)block.tree).sym == sym &&
- sym.owner.kind == MTH) { //only locals are captured
+ if ((((JCVariableDecl)block.tree).sym == sym &&
+ sym.owner.kind == MTH) || //only locals are captured
+ (block.locals != null && block.locals.contains(sym))) {
return currentDepth > depth ? null : block.tree;
}
break;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Mon Jul 22 11:08:27 2019 +0530
@@ -299,6 +299,8 @@
if (chk.checkUnique(tree.pos(), v, enclScope)) {
chk.checkTransparentVar(tree.pos(), v, enclScope);
enclScope.enter(v);
+ } else if (v.owner.kind == MTH) {
+ enclScope.enter(v);
}
annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Mon Jul 22 11:08:27 2019 +0530
@@ -99,6 +99,10 @@
*/
protected boolean shouldTranslateEscapes;
+ /** Has the string broken escapes?
+ */
+ protected boolean hasBrokenEscapes;
+
protected ScannerFactory fac;
// The set of lint options currently in effect. It is initialized
@@ -261,6 +265,7 @@
case '\\':
reader.putChar(true); break;
default:
+ hasBrokenEscapes = true;
lexError(reader.bp, Errors.IllegalEscChar);
}
}
@@ -426,6 +431,7 @@
// Clear flags.
shouldStripIndent = false;
shouldTranslateEscapes = false;
+ hasBrokenEscapes = false;
// Check if text block string methods are present.
boolean hasTextBlockSupport = TextBlockSupport.hasSupport();
// Track the end of first line for error recovery.
@@ -1038,7 +1044,7 @@
string = TextBlockSupport.stripIndent(string);
}
// Translate escape sequences if present.
- if (shouldTranslateEscapes) {
+ if (shouldTranslateEscapes && !hasBrokenEscapes) {
string = TextBlockSupport.translateEscapes(string);
}
// Build string token.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Jul 22 11:08:27 2019 +0530
@@ -775,9 +775,9 @@
public JCExpression unannotatedType(boolean allowVar) {
JCExpression result = term(TYPE);
- Name restrictedTypeName;
-
- if (!allowVar && (restrictedTypeName = restrictedTypeName(result, true)) != null) {
+ Name restrictedTypeName = restrictedTypeName(result, !allowVar);
+
+ if (restrictedTypeName != null && (!allowVar || restrictedTypeName != names.var)) {
syntaxError(result.pos, Errors.RestrictedTypeNotAllowedHere(restrictedTypeName));
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -159,25 +159,23 @@
compiler.err.break.outside.switch.loop=break\u304Cswitch\u6587\u307E\u305F\u306F\u30EB\u30FC\u30D7\u306E\u5916\u306B\u3042\u308A\u307E\u3059
-compiler.err.break.missing.value=break\u306E\u5024\u304C\u3042\u308A\u307E\u305B\u3093
-
-compiler.err.break.outside.switch.expression=break\u304C\u3001\u56F2\u3093\u3067\u3044\u308Bswitch\u5F0F\u306E\u5916\u306B\u3042\u308A\u307E\u3059
-
-compiler.err.continue.outside.switch.expression=continue\u304C\u3001\u56F2\u3093\u3067\u3044\u308Bswitch\u5F0F\u306E\u5916\u306B\u3042\u308A\u307E\u3059
-
-compiler.err.return.outside.switch.expression=return\u304C\u3001\u56F2\u3093\u3067\u3044\u308Bswitch\u5F0F\u306E\u5916\u306B\u3042\u308A\u307E\u3059
+compiler.err.break.outside.switch.expression=switch\u5F0F\u306E\u5916\u5074\u3067break\u3092\u5B9F\u884C\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059
+
+compiler.err.continue.outside.switch.expression=switch\u5F0F\u306E\u5916\u5074\u3067continue\u3092\u5B9F\u884C\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059
+
+compiler.err.return.outside.switch.expression=switch\u5F0F\u306E\u5916\u5074\u3067return\u3092\u5B9F\u884C\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059
compiler.err.rule.completes.normally=switch\u30EB\u30FC\u30EB\u304C\u5024\u3092\u63D0\u4F9B\u305B\u305A\u306B\u5B8C\u4E86\u3057\u307E\u3057\u305F\n(switch\u5F0F\u306Eswitch\u30EB\u30FC\u30EB\u306F\u5024\u307E\u305F\u306F\u30B9\u30ED\u30FC\u3092\u63D0\u4F9B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059)
compiler.err.switch.expression.completes.normally=switch\u5F0F\u304C\u5024\u3092\u63D0\u4F9B\u305B\u305A\u306B\u5B8C\u4E86\u3057\u307E\u3057\u305F\n(switch\u5F0F\u306F\u3059\u3079\u3066\u306E\u53EF\u80FD\u306A\u5165\u529B\u5024\u306B\u3064\u3044\u3066\u5024\u307E\u305F\u306F\u30B9\u30ED\u30FC\u3092\u63D0\u4F9B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059)
-# 0: name
-compiler.err.break.ambiguous.target=''{0}''\u3078\u306E\u53C2\u7167\u304C\u3042\u3044\u307E\u3044\u3067\u3059\n(''{0}''\u306F\u30E9\u30D9\u30EB\u3068\u5F0F\u306E\u4E21\u65B9\u3067\u3059)
-
-# 0: tree tag
-compiler.err.break.expr.not.immediate=\u5024\u30D6\u30EC\u30FC\u30AF\u306F''{0}''\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093
-
-compiler.err.break.complex.value.no.switch.expression=\u4E88\u671F\u3057\u306A\u3044\u5024\u30D6\u30EC\u30FC\u30AF\u3067\u3059
+compiler.err.no.switch.expression =switch\u5F0F\u306E\u5916\u5074\u306Eyield
+
+compiler.err.no.switch.expression.qualify=switch\u5F0F\u306E\u5916\u5074\u306Eyield\n(yield\u3068\u3044\u3046\u30E1\u30BD\u30C3\u30C9\u3092\u547C\u3073\u51FA\u3059\u306B\u306F\u3001yield\u3092\u53D7\u53D6\u308A\u5074\u307E\u305F\u306F\u30BF\u30A4\u30D7\u540D\u3067\u4FEE\u98FE\u3057\u307E\u3059)
+
+compiler.err.invalid.yield=\u5236\u9650\u3055\u308C\u305F\u8B58\u5225\u5B50''yield''\u306E\u4F7F\u7528\u306F\u7121\u52B9\u3067\u3059\n(yield\u3068\u3044\u3046\u30E1\u30BD\u30C3\u30C9\u3092\u547C\u3073\u51FA\u3059\u306B\u306F\u3001yield\u3092\u53D7\u53D6\u308A\u5074\u307E\u305F\u306F\u30BF\u30A4\u30D7\u540D\u3067\u4FEE\u98FE\u3057\u307E\u3059)
+
+compiler.warn.invalid.yield=''yield''\u306F\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u5236\u9650\u3055\u308C\u305F\u8B58\u5225\u5B50\u306B\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\n(yield\u3068\u3044\u3046\u30E1\u30BD\u30C3\u30C9\u3092\u547C\u3073\u51FA\u3059\u306B\u306F\u3001yield\u3092\u53D7\u53D6\u308A\u5074\u307E\u305F\u306F\u30BF\u30A4\u30D7\u540D\u3067\u4FEE\u98FE\u3057\u307E\u3059)
compiler.err.switch.expression.empty=switch\u5F0F\u306Bcase\u53E5\u304C\u3042\u308A\u307E\u305B\u3093
@@ -185,13 +183,13 @@
compiler.err.call.must.be.first.stmt.in.ctor={0}\u306E\u547C\u51FA\u3057\u306F\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u306E\u5148\u982D\u6587\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
# 0: symbol kind, 1: name, 2: list of type or message segment, 3: list of type or message segment, 4: symbol kind, 5: type, 6: message segment
-compiler.err.cant.apply.symbol={4} {5}\u306E{0} {1}\u306F\u6307\u5B9A\u3055\u308C\u305F\u578B\u306B\u9069\u7528\u3067\u304D\u307E\u305B\u3093\u3002\n\u671F\u5F85\u5024: {2}\n\u691C\u51FA\u5024: {3}\n\u7406\u7531: {6}
+compiler.err.cant.apply.symbol={4} {5}\u306E{0} {1}\u306F\u6307\u5B9A\u3055\u308C\u305F\u578B\u306B\u9069\u7528\u3067\u304D\u307E\u305B\u3093\u3002\n\u671F\u5F85\u5024: {2}\n\u691C\u51FA\u5024: {3}\n\u7406\u7531: {6}
# 0: symbol kind, 1: name, 2: list of type
compiler.err.cant.apply.symbols={1}\u306B\u9069\u5207\u306A{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093({2})
# 0: symbol kind, 1: name, 2: list of type or message segment, 3: list of type or message segment, 4: symbol kind, 5: type, 6: message segment
-compiler.misc.cant.apply.symbol={4} {5}\u306E{0} {1}\u306F\u6307\u5B9A\u3055\u308C\u305F\u578B\u306B\u9069\u7528\u3067\u304D\u307E\u305B\u3093\n\u671F\u5F85\u5024: {2}\n\u691C\u51FA\u5024: {3}\n\u7406\u7531: {6}
+compiler.misc.cant.apply.symbol={4} {5}\u306E{0} {1}\u306F\u6307\u5B9A\u3055\u308C\u305F\u578B\u306B\u9069\u7528\u3067\u304D\u307E\u305B\u3093\n\u671F\u5F85\u5024: {2}\n\u691C\u51FA\u5024: {3}\n\u7406\u7531: {6}
# 0: symbol kind, 1: name, 2: list of type
compiler.misc.cant.apply.symbols={1}\u306B\u9069\u5207\u306A{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093({2})
@@ -459,6 +457,12 @@
compiler.err.illegal.line.end.in.char.lit=\u6587\u5B57\u30EA\u30C6\u30E9\u30EB\u306E\u884C\u672B\u304C\u4E0D\u6B63\u3067\u3059
+compiler.err.illegal.text.block.open=\u30C6\u30AD\u30B9\u30C8\u30FB\u30D6\u30ED\u30C3\u30AF\u306E\u958B\u59CB\u533A\u5207\u308A\u6587\u5B57\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u304C\u7121\u52B9\u3067\u3059\u3002\u884C\u306E\u7D42\u4E86\u6587\u5B57\u304C\u3042\u308A\u307E\u305B\u3093
+
+compiler.warn.inconsistent.white.space.indentation=\u7A7A\u767D\u306E\u30A4\u30F3\u30C7\u30F3\u30C8\u306B\u4E00\u8CAB\u6027\u304C\u3042\u308A\u307E\u305B\u3093
+
+compiler.warn.trailing.white.space.will.be.removed=\u672B\u5C3E\u306E\u7A7A\u767D\u306F\u9664\u53BB\u3055\u308C\u307E\u3059
+
compiler.err.illegal.nonascii.digit=\u4E0D\u6B63\u306A\u975EASCII\u6570\u5B57\u3067\u3059
compiler.err.illegal.underscore=\u4E0D\u6B63\u306A\u30A2\u30F3\u30C0\u30FC\u30B9\u30B3\u30A2\u3067\u3059
@@ -756,6 +760,9 @@
# 0: string
compiler.err.proc.cant.find.class=''{0}''\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
+# 0: string
+compiler.err.proc.cant.load.class=''{0}''\u304C\u539F\u56E0\u3067\u3001\u30D7\u30ED\u30BB\u30C3\u30B5\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30ED\u30FC\u30C9\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
+
# Print a client-generated error message; assumed to be localized, no translation required
# 0: string
compiler.err.proc.messager={0}
@@ -888,7 +895,7 @@
compiler.err.unclosed.str.lit=\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u304C\u9589\u3058\u3089\u308C\u3066\u3044\u307E\u305B\u3093
-compiler.err.unicode.backtick=RAW\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u306E\u30C7\u30EA\u30DF\u30BF\u3068\u3057\u3066\\u0060\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F
+compiler.err.unclosed.text.block=\u9589\u3058\u3089\u308C\u3066\u3044\u306A\u3044\u30C6\u30AD\u30B9\u30C8\u30FB\u30D6\u30ED\u30C3\u30AF
# 0: string
compiler.err.unsupported.encoding=\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3067\u3059: {0}
@@ -898,20 +905,32 @@
# 0: name
compiler.err.undef.label=\u30E9\u30D9\u30EB{0}\u306F\u672A\u5B9A\u7FA9\u3067\u3059
-compiler.err.illegal.ref.to.var.type=\u5236\u9650\u3055\u308C\u305F\u578B''var''\u3078\u306E\u7121\u52B9\u306A\u53C2\u7167\u3067\u3059
-
-compiler.err.var.not.allowed=\u3053\u3053\u3067\u306F''var''\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\n\u30EA\u30EA\u30FC\u30B910\u304B\u3089\u3001''var''\u306F\u5236\u9650\u3055\u308C\u305F\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u578B\u3067\u3042\u308A\u3001\u578B\u306E\u5BA3\u8A00\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
-
-compiler.warn.var.not.allowed=\u30EA\u30EA\u30FC\u30B910\u304B\u3089\u3001''var''\u306F\u5236\u9650\u3055\u308C\u305F\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u578B\u3067\u3042\u308A\u3001\u578B\u306E\u5BA3\u8A00\u3067\u306E\u4F7F\u7528\u3001\u307E\u305F\u306F\u914D\u5217\u306E\u8981\u7D20\u30BF\u30A4\u30D7\u3068\u3057\u3066\u306E\u4F7F\u7528\u306F\u3067\u304D\u307E\u305B\u3093
+# 0: name
+compiler.err.illegal.ref.to.restricted.type=\u5236\u9650\u3055\u308C\u305F\u578B''{0}''\u3078\u306E\u7121\u52B9\u306A\u53C2\u7167\u3067\u3059
+
+# 0: name
+compiler.warn.illegal.ref.to.restricted.type=\u5236\u9650\u3055\u308C\u305F\u578B''{0}''\u3078\u306E\u7121\u52B9\u306A\u53C2\u7167\u3067\u3059
+
+# 0: name, 1: source
+compiler.err.restricted.type.not.allowed=\u3053\u3053\u3067\u306F''{0}''\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\n\u30EA\u30EA\u30FC\u30B9{1}\u304B\u3089''{0}''\u306F\u5236\u9650\u3055\u308C\u305F\u578B\u540D\u3067\u3042\u308A\u3001\u578B\u306E\u5BA3\u8A00\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
+
+# 0: name, 1: source
+compiler.warn.restricted.type.not.allowed=\u30EA\u30EA\u30FC\u30B9{1}\u304B\u3089\u3001''{0}''\u306F\u5236\u9650\u3055\u308C\u305F\u578B\u540D\u3067\u3042\u308A\u3001\u578B\u306E\u5BA3\u8A00\u3067\u306E\u4F7F\u7528\u3001\u307E\u305F\u306F\u914D\u5217\u306E\u8981\u7D20\u30BF\u30A4\u30D7\u3068\u3057\u3066\u306E\u4F7F\u7528\u306F\u3067\u304D\u307E\u305B\u3093
+
+# 0: name, 1: source
+compiler.warn.restricted.type.not.allowed.preview=''{0}''\u306F\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u5236\u9650\u3055\u308C\u305F\u578B\u540D\u306B\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u3001\u578B\u306E\u5BA3\u8A00\u3067\u306E\u4F7F\u7528\u3001\u307E\u305F\u306F\u914D\u5217\u306E\u8981\u7D20\u30BF\u30A4\u30D7\u3068\u3057\u3066\u306E\u4F7F\u7528\u306F\u3067\u304D\u306A\u304F\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
# 0: name (variable), 1: message segment
compiler.err.cant.infer.local.var.type=\u30ED\u30FC\u30AB\u30EB\u5909\u6570{0}\u306E\u578B\u3092\u63A8\u8AD6\u3067\u304D\u307E\u305B\u3093\n({1})
-compiler.err.var.not.allowed.here=\u3053\u3053\u3067\u306F''var''\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
-
-compiler.err.var.not.allowed.array=''var''\u306F\u914D\u5217\u306E\u8981\u7D20\u30BF\u30A4\u30D7\u3068\u3057\u3066\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
-
-compiler.err.var.not.allowed.compound=''var''\u306F\u8907\u5408\u5BA3\u8A00\u3067\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
+# 0: name
+compiler.err.restricted.type.not.allowed.here=''{0}''\u306F\u3053\u3053\u3067\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
+
+# 0: name
+compiler.err.restricted.type.not.allowed.array=''{0}''\u306F\u914D\u5217\u306E\u8981\u7D20\u30BF\u30A4\u30D7\u3068\u3057\u3066\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
+
+# 0: name
+compiler.err.restricted.type.not.allowed.compound=''{0}''\u306F\u8907\u5408\u5BA3\u8A00\u3067\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
# 0: fragment
compiler.err.invalid.lambda.parameter.declaration=\u7121\u52B9\u306A\u30E9\u30E0\u30C0\u30FB\u30D1\u30E9\u30E1\u30FC\u30BF\u5BA3\u8A00\n({0})
@@ -1175,6 +1194,12 @@
# 0: number
compiler.misc.count.error.plural=\u30A8\u30E9\u30FC{0}\u500B
+# 0: number, 1: number
+compiler.misc.count.error.recompile=\u5408\u8A08{1}\u500B\u306E\u3046\u3061\u3001\u6700\u521D\u306E{0}\u500B\u306E\u30A8\u30E9\u30FC\u306E\u307F\u8868\u793A\u3057\u3066\u3044\u307E\u3059\u3002\u3055\u3089\u306B\u8868\u793A\u3059\u308B\u5834\u5408\u306F\u3001-Xmaxerrs\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
+
+# 0: number, 1: number
+compiler.misc.count.warn.recompile=\u5408\u8A08{1}\u500B\u306E\u3046\u3061\u3001\u6700\u521D\u306E{0}\u500B\u306E\u8B66\u544A\u306E\u307F\u8868\u793A\u3057\u3066\u3044\u307E\u3059\u3002\u3055\u3089\u306B\u8868\u793A\u3059\u308B\u5834\u5408\u306F\u3001-Xmaxwarns\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
+
# 0: number
compiler.misc.count.warn=\u8B66\u544A{0}\u500B
@@ -1370,6 +1395,15 @@
# 0: source version, 1: string, 2: string
compiler.warn.proc.processor.incompatible.source.version=\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5''{1}''\u304B\u3089-source ''{2}''\u3088\u308A\u5C0F\u3055\u3044\u30BD\u30FC\u30B9\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3''{0}''\u304C\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059
+# 0: string, 1: string
+compiler.warn.proc.duplicate.option.name=\u91CD\u8907\u3059\u308B\u30B5\u30DD\u30FC\u30C8\u5BFE\u8C61\u30AA\u30D7\u30B7\u30E7\u30F3''{0}''\u304C\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5''{1}''\u306B\u3088\u3063\u3066\u8FD4\u3055\u308C\u307E\u3057\u305F
+
+# 0: string, 1: string
+compiler.warn.proc.duplicate.supported.annotation=\u91CD\u8907\u3059\u308B\u30B5\u30DD\u30FC\u30C8\u5BFE\u8C61\u6CE8\u91C8\u578B''{0}''\u304C\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5''{1}''\u306B\u3088\u3063\u3066\u8FD4\u3055\u308C\u307E\u3057\u305F
+
+# 0: string
+compiler.warn.proc.redundant.types.with.wildcard=\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5''{0}''\u306F''*''\u3068\u4ED6\u306E\u6CE8\u91C8\u578B\u3092\u91CD\u8907\u3057\u3066\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059
+
compiler.warn.proc.proc-only.requested.no.procs=\u30B3\u30F3\u30D1\u30A4\u30EB\u306A\u3057\u306E\u6CE8\u91C8\u51E6\u7406\u304C\u30EA\u30AF\u30A8\u30B9\u30C8\u3055\u308C\u307E\u3057\u305F\u304C\u3001\u30D7\u30ED\u30BB\u30C3\u30B5\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
compiler.warn.proc.use.implicit=\u6697\u9ED9\u7684\u306B\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u306F\u6CE8\u91C8\u51E6\u7406\u306B\u6E21\u3055\u308C\u307E\u305B\u3093\u3002\n-implicit\u3092\u4F7F\u7528\u3057\u6697\u9ED9\u7684\u30B3\u30F3\u30D1\u30A4\u30EB\u306E\u30DD\u30EA\u30B7\u30FC\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002
@@ -1405,7 +1439,7 @@
compiler.warn.unchecked.cast.to.type=\u578B{0}\u3078\u306E\u7121\u691C\u67FB\u30AD\u30E3\u30B9\u30C8\u3067\u3059
# 0: kind name, 1: name, 2: object, 3: object, 4: kind name, 5: symbol
-compiler.warn.unchecked.meth.invocation.applied=\u7121\u691C\u67FB\u30E1\u30BD\u30C3\u30C9\u547C\u51FA\u3057: {4} {5}\u306E{0} {1}\u306F\u6307\u5B9A\u3055\u308C\u305F\u578B\u306B\u9069\u7528\u3055\u308C\u307E\u3059\n\u671F\u5F85\u5024: {2}\n\u691C\u51FA\u5024: {3}
+compiler.warn.unchecked.meth.invocation.applied=\u7121\u691C\u67FB\u30E1\u30BD\u30C3\u30C9\u547C\u51FA\u3057: {4} {5}\u306E{0} {1}\u306F\u6307\u5B9A\u3055\u308C\u305F\u578B\u306B\u9069\u7528\u3055\u308C\u307E\u3059\n\u671F\u5F85\u5024: {2}\n\u691C\u51FA\u5024: {3}
# 0: type
compiler.warn.unchecked.generic.array.creation=\u578B{0}\u306E\u53EF\u5909\u5F15\u6570\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u5BFE\u3059\u308B\u7DCF\u79F0\u578B\u914D\u5217\u306E\u7121\u691C\u67FB\u4F5C\u6210\u3067\u3059
@@ -1424,6 +1458,10 @@
# 0: string
compiler.warn.invalid.path=\u30D5\u30A1\u30A4\u30EB\u540D\u304C\u7121\u52B9\u3067\u3059: {0}
+# 0: string
+compiler.err.invalid.path=\u30D5\u30A1\u30A4\u30EB\u540D\u304C\u7121\u52B9\u3067\u3059: {0}
+
+
# 0: path
compiler.warn.invalid.archive.file=\u30D1\u30B9\u4E0A\u306E\u4E88\u671F\u3057\u306A\u3044\u30D5\u30A1\u30A4\u30EB: {0}
@@ -1550,6 +1588,9 @@
# 0: file name, 1: string (expected constant pool entry type), 2: number (constant pool index)
compiler.misc.bad.const.pool.entry={0}\u306E\u5B9A\u6570\u30D7\u30FC\u30EB\u30FB\u30A8\u30F3\u30C8\u30EA\u304C\u4E0D\u6B63\u3067\u3059\n\u7D22\u5F15{2}\u3067\u306F{1}\u304C\u5FC5\u8981\u3067\u3059
+# 0: file name, 1: number (constant pool index), 2: number (constant pool size)
+compiler.misc.bad.const.pool.index={0}\u306E\u5B9A\u6570\u30D7\u30FC\u30EB\u7D22\u5F15\u304C\u4E0D\u6B63\u3067\u3059\n\u7D22\u5F15{1}\u304C{2}\u306E\u30D7\u30FC\u30EB\u30FB\u30B5\u30A4\u30BA\u5185\u306B\u3042\u308A\u307E\u305B\u3093\u3002
+
# 0: file name, 1: message segment
compiler.misc.bad.class.file.header=\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB{0}\u306F\u4E0D\u6B63\u3067\u3059\n{1}\n\u524A\u9664\u3059\u308B\u304B\u3001\u30AF\u30E9\u30B9\u30D1\u30B9\u306E\u6B63\u3057\u3044\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u3042\u308B\u304B\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
@@ -1876,17 +1917,6 @@
compiler.misc.kindname.instance.init=\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u521D\u671F\u5316\u5B50
-# the following are names of tree kinds:
-compiler.misc.tree.tag.forloop=for
-
-compiler.misc.tree.tag.foreachloop=for
-
-compiler.misc.tree.tag.whileloop=while
-
-compiler.misc.tree.tag.doloop=do
-
-compiler.misc.tree.tag.switch=switch
-
#####
compiler.misc.no.args=\u5F15\u6570\u304C\u3042\u308A\u307E\u305B\u3093
@@ -2017,14 +2047,14 @@
compiler.misc.feature.private.intf.methods=private\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u30FB\u30E1\u30BD\u30C3\u30C9
+compiler.misc.feature.text.blocks=\u30C6\u30AD\u30B9\u30C8\u30FB\u30D6\u30ED\u30C3\u30AF
+
compiler.misc.feature.multiple.case.labels=\u8907\u6570\u306Ecase\u30E9\u30D9\u30EB
compiler.misc.feature.switch.rules=switch\u30EB\u30FC\u30EB
compiler.misc.feature.switch.expressions=switch\u5F0F
-compiler.misc.feature.raw.string.literals=RAW\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB
-
compiler.misc.feature.var.syntax.in.implicit.lambda=\u6697\u9ED9\u30E9\u30E0\u30C0\u306Evar\u69CB\u6587
compiler.warn.underscore.as.identifier=\u30EA\u30EA\u30FC\u30B99\u304B\u3089''_''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093
@@ -2051,16 +2081,16 @@
compiler.err.cant.type.annotate.scoping=\u30B9\u30B3\u30FC\u30D7\u30FB\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30C8\u3092\u578B\u4F7F\u7528\u6CE8\u91C8\u3067\u6CE8\u91C8\u4ED8\u3051\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093: {0}
# 0: type, 1: type
-compiler.err.incorrect.receiver.name=\u53D7\u53D6\u308A\u5074\u306E\u540D\u524D\u304C\u3001\u5305\u542B\u3059\u308B\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
+compiler.err.incorrect.receiver.name=\u53D7\u53D6\u308A\u5074\u306E\u540D\u524D\u304C\u3001\u5305\u542B\u3059\u308B\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
# 0: type, 1: type
-compiler.err.incorrect.receiver.type=\u53D7\u53D6\u308A\u5074\u306E\u30BF\u30A4\u30D7\u304C\u3001\u5305\u542B\u3059\u308B\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
+compiler.err.incorrect.receiver.type=\u53D7\u53D6\u308A\u5074\u306E\u30BF\u30A4\u30D7\u304C\u3001\u5305\u542B\u3059\u308B\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
# 0: type, 1: type
-compiler.err.incorrect.constructor.receiver.type=\u53D7\u53D6\u308A\u5074\u306E\u30BF\u30A4\u30D7\u304C\u3001\u5305\u542B\u3059\u308B\u5916\u90E8\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
+compiler.err.incorrect.constructor.receiver.type=\u53D7\u53D6\u308A\u5074\u306E\u30BF\u30A4\u30D7\u304C\u3001\u5305\u542B\u3059\u308B\u5916\u90E8\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
# 0: type, 1: type
-compiler.err.incorrect.constructor.receiver.name=\u53D7\u53D6\u308A\u5074\u306E\u540D\u524D\u304C\u3001\u5305\u542B\u3059\u308B\u5916\u90E8\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
+compiler.err.incorrect.constructor.receiver.name=\u53D7\u53D6\u308A\u5074\u306E\u540D\u524D\u304C\u3001\u5305\u542B\u3059\u308B\u5916\u90E8\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1}
compiler.err.no.annotations.on.dot.class=\u6CE8\u91C8\u306F\u30AF\u30E9\u30B9\u30FB\u30EA\u30C6\u30E9\u30EB\u306E\u30BF\u30A4\u30D7\u3067\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
@@ -2331,7 +2361,7 @@
# 0: option name, 1: symbol
compiler.warn.module.for.option.not.found={0}\u30AA\u30D7\u30B7\u30E7\u30F3\u5185\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {1}
-compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH\u306F\u3001\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059
+compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH\u306F\u3001\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u307E\u305F\u306F\u81EA\u52D5\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059
# 0: symbol
compiler.err.add.exports.with.release=\u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB{0}\u304B\u3089\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u306F--release\u3092\u6307\u5B9A\u3057\u3066\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -159,25 +159,23 @@
compiler.err.break.outside.switch.loop=\u5728 switch \u6216 loop \u5916\u90E8\u4E2D\u65AD
-compiler.err.break.missing.value=\u7F3A\u5C11\u4E2D\u65AD\u503C
-
-compiler.err.break.outside.switch.expression=break \u5728\u95ED\u5408\u7684 switch \u8868\u8FBE\u5F0F\u5916\u90E8
-
-compiler.err.continue.outside.switch.expression=continue \u5728\u95ED\u5408\u7684 switch \u8868\u8FBE\u5F0F\u5916\u90E8
-
-compiler.err.return.outside.switch.expression=return \u5728\u95ED\u5408\u7684 switch \u8868\u8FBE\u5F0F\u5916\u90E8
+compiler.err.break.outside.switch.expression=\u5C1D\u8BD5\u4ECE switch \u8868\u8FBE\u5F0F\u4E2D\u65AD
+
+compiler.err.continue.outside.switch.expression=\u5C1D\u8BD5\u4ECE switch \u8868\u8FBE\u5F0F\u7EE7\u7EED
+
+compiler.err.return.outside.switch.expression=\u5C1D\u8BD5\u4ECE switch \u8868\u8FBE\u5F0F\u8FD4\u56DE
compiler.err.rule.completes.normally=switch \u89C4\u5219\u5B8C\u7ED3\u4F46\u6CA1\u6709\u63D0\u4F9B\u503C\n\uFF08switch \u8868\u8FBE\u5F0F\u4E2D\u7684 switch \u89C4\u5219\u5FC5\u987B\u63D0\u4F9B\u503C\u6216\u629B\u51FA\uFF09
compiler.err.switch.expression.completes.normally=switch \u8868\u8FBE\u5F0F\u5B8C\u7ED3\u4F46\u6CA1\u6709\u63D0\u4F9B\u503C\n\uFF08switch \u8868\u8FBE\u5F0F\u5FC5\u987B\u4E3A\u6240\u6709\u53EF\u80FD\u7684\u8F93\u5165\u503C\u63D0\u4F9B\u503C\u6216\u629B\u51FA\uFF09
-# 0: name
-compiler.err.break.ambiguous.target=\u5BF9 ''{0}'' \u7684\u5F15\u7528\u4E0D\u660E\u786E\n\uFF08''{0}'' \u540C\u65F6\u662F\u6807\u7B7E\u548C\u8868\u8FBE\u5F0F\uFF09
-
-# 0: tree tag
-compiler.err.break.expr.not.immediate=''{0}'' \u4E2D\u4E0D\u652F\u6301\u503C\u4E2D\u65AD
-
-compiler.err.break.complex.value.no.switch.expression=\u610F\u5916\u503C\u4E2D\u65AD
+compiler.err.no.switch.expression =yield \u5728 switch \u8868\u8FBE\u5F0F\u5916\u90E8
+
+compiler.err.no.switch.expression.qualify=yield \u5728 switch \u8868\u8FBE\u5F0F\u5916\u90E8\n\uFF08\u8981\u8C03\u7528\u79F0\u4E3A yield \u7684\u65B9\u6CD5\uFF0C\u8BF7\u901A\u8FC7\u63A5\u6536\u65B9\u6216\u7C7B\u578B\u540D\u79F0\u9650\u5B9A yield\uFF09
+
+compiler.err.invalid.yield=\u53D7\u9650\u6807\u8BC6\u7B26 ''yield'' \u7684\u7528\u6CD5\u65E0\u6548\n\uFF08\u8981\u8C03\u7528\u79F0\u4E3A yield \u7684\u65B9\u6CD5\uFF0C\u8BF7\u901A\u8FC7\u63A5\u6536\u65B9\u6216\u7C7B\u578B\u540D\u79F0\u9650\u5B9A yield\uFF09
+
+compiler.warn.invalid.yield=''yield'' \u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u53EF\u80FD\u4F1A\u6210\u4E3A\u53D7\u9650\u6807\u8BC6\u7B26\n\uFF08\u8981\u8C03\u7528\u79F0\u4E3A yield \u7684\u65B9\u6CD5\uFF0C\u8BF7\u901A\u8FC7\u63A5\u6536\u65B9\u6216\u7C7B\u578B\u540D\u79F0\u9650\u5B9A yield\uFF09
compiler.err.switch.expression.empty=switch \u8868\u8FBE\u5F0F\u4E2D\u6CA1\u6709\u4EFB\u4F55 case \u5B50\u53E5
@@ -185,13 +183,13 @@
compiler.err.call.must.be.first.stmt.in.ctor=\u5BF9{0}\u7684\u8C03\u7528\u5FC5\u987B\u662F\u6784\u9020\u5668\u4E2D\u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5
# 0: symbol kind, 1: name, 2: list of type or message segment, 3: list of type or message segment, 4: symbol kind, 5: type, 6: message segment
-compiler.err.cant.apply.symbol=\u65E0\u6CD5\u5C06{4} {5}\u4E2D\u7684{0} {1}\u5E94\u7528\u5230\u7ED9\u5B9A\u7C7B\u578B;\n\u9700\u8981: {2}\n\u627E\u5230: {3}\n\u539F\u56E0: {6}
+compiler.err.cant.apply.symbol=\u65E0\u6CD5\u5C06{4} {5}\u4E2D\u7684{0} {1}\u5E94\u7528\u5230\u7ED9\u5B9A\u7C7B\u578B;\n\u9700\u8981: {2}\n\u627E\u5230: {3}\n\u539F\u56E0: {6}
# 0: symbol kind, 1: name, 2: list of type
compiler.err.cant.apply.symbols=\u5BF9\u4E8E{1}({2}), \u627E\u4E0D\u5230\u5408\u9002\u7684{0}
# 0: symbol kind, 1: name, 2: list of type or message segment, 3: list of type or message segment, 4: symbol kind, 5: type, 6: message segment
-compiler.misc.cant.apply.symbol=\u65E0\u6CD5\u5C06 {4} {5}\u4E2D\u7684 {0} {1}\u5E94\u7528\u5230\u7ED9\u5B9A\u7C7B\u578B\n\u9700\u8981: {2}\n\u627E\u5230: {3}\n\u539F\u56E0: {6}
+compiler.misc.cant.apply.symbol=\u65E0\u6CD5\u5C06 {4} {5}\u4E2D\u7684 {0} {1}\u5E94\u7528\u5230\u7ED9\u5B9A\u7C7B\u578B\n\u9700\u8981: {2}\n\u627E\u5230: {3}\n\u539F\u56E0: {6}
# 0: symbol kind, 1: name, 2: list of type
compiler.misc.cant.apply.symbols=\u5BF9\u4E8E{1}({2}), \u627E\u4E0D\u5230\u5408\u9002\u7684{0}
@@ -459,6 +457,12 @@
compiler.err.illegal.line.end.in.char.lit=\u5B57\u7B26\u6587\u5B57\u7684\u884C\u7ED3\u5C3E\u4E0D\u5408\u6CD5
+compiler.err.illegal.text.block.open=\u6587\u672C\u5757\u8D77\u59CB\u5206\u9694\u7B26\u5E8F\u5217\u975E\u6CD5\uFF0C\u7F3A\u5C11\u884C\u7EC8\u6B62\u7B26
+
+compiler.warn.inconsistent.white.space.indentation=\u7A7A\u683C\u7F29\u8FDB\u4E0D\u4E00\u81F4
+
+compiler.warn.trailing.white.space.will.be.removed=\u5C06\u5220\u9664\u5C3E\u968F\u7A7A\u683C
+
compiler.err.illegal.nonascii.digit=\u975E\u6CD5\u7684\u975E ASCII \u6570\u5B57
compiler.err.illegal.underscore=\u975E\u6CD5\u4E0B\u5212\u7EBF
@@ -756,6 +760,9 @@
# 0: string
compiler.err.proc.cant.find.class=\u627E\u4E0D\u5230 ''{0}'' \u7684\u7C7B\u6587\u4EF6\u3002
+# 0: string
+compiler.err.proc.cant.load.class=\u7531\u4E8E ''{0}''\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u5904\u7406\u5668\u7C7B\u6587\u4EF6\u3002
+
# Print a client-generated error message; assumed to be localized, no translation required
# 0: string
compiler.err.proc.messager={0}
@@ -888,7 +895,7 @@
compiler.err.unclosed.str.lit=\u672A\u7ED3\u675F\u7684\u5B57\u7B26\u4E32\u6587\u5B57
-compiler.err.unicode.backtick=\u5C1D\u8BD5\u5C06 \\u0060 \u7528\u4F5C\u539F\u59CB\u5B57\u7B26\u4E32\u6587\u5B57\u5206\u9694\u7B26
+compiler.err.unclosed.text.block=\u6587\u672C\u5757\u672A\u95ED\u5408
# 0: string
compiler.err.unsupported.encoding=\u4E0D\u652F\u6301\u7684\u7F16\u7801: {0}
@@ -898,20 +905,32 @@
# 0: name
compiler.err.undef.label=\u672A\u5B9A\u4E49\u7684\u6807\u7B7E: {0}
-compiler.err.illegal.ref.to.var.type=\u5BF9\u53D7\u9650\u5236\u7C7B\u578B ''var'' \u7684\u5F15\u7528\u975E\u6CD5
-
-compiler.err.var.not.allowed=\u4ECE\u53D1\u884C\u7248 10 \u5F00\u59CB\uFF0C\n\u6B64\u5904\u4E0D\u5141\u8BB8\u4F7F\u7528 ''var''\uFF0C''var'' \u662F\u53D7\u9650\u5236\u7684\u672C\u5730\u53D8\u91CF\u7C7B\u578B\uFF0C\u65E0\u6CD5\u7528\u4E8E\u7C7B\u578B\u58F0\u660E
-
-compiler.warn.var.not.allowed=\u4ECE\u53D1\u884C\u7248 10 \u5F00\u59CB\uFF0C''var'' \u662F\u53D7\u9650\u5236\u7684\u672C\u5730\u53D8\u91CF\u7C7B\u578B\uFF0C\u65E0\u6CD5\u7528\u4E8E\u7C7B\u578B\u58F0\u660E\uFF0C\u4E5F\u65E0\u6CD5\u7528\u4F5C\u6570\u7EC4\u7684\u5143\u7D20\u7C7B\u578B
+# 0: name
+compiler.err.illegal.ref.to.restricted.type=\u5BF9\u53D7\u9650\u5236\u7C7B\u578B ''{0}'' \u7684\u5F15\u7528\u975E\u6CD5
+
+# 0: name
+compiler.warn.illegal.ref.to.restricted.type=\u5BF9\u53D7\u9650\u5236\u7C7B\u578B ''{0}'' \u7684\u5F15\u7528\u975E\u6CD5
+
+# 0: name, 1: source
+compiler.err.restricted.type.not.allowed=\u6B64\u5904\u4E0D\u5141\u8BB8\u4F7F\u7528 ''{0}''\n\u4ECE\u53D1\u884C\u7248 {1} \u5F00\u59CB\uFF0C''{0}'' \u662F\u53D7\u9650\u7C7B\u578B\u540D\u79F0\uFF0C\u4E0D\u80FD\u7528\u4E8E\u7C7B\u578B\u58F0\u660E
+
+# 0: name, 1: source
+compiler.warn.restricted.type.not.allowed=\u4ECE\u53D1\u884C\u7248 {1} \u5F00\u59CB\uFF0C''{0}'' \u662F\u53D7\u9650\u7C7B\u578B\u540D\u79F0\uFF0C\u4E0D\u80FD\u7528\u4E8E\u7C7B\u578B\u58F0\u660E\uFF0C\u4E5F\u4E0D\u80FD\u7528\u4F5C\u6570\u7EC4\u7684\u5143\u7D20\u7C7B\u578B
+
+# 0: name, 1: source
+compiler.warn.restricted.type.not.allowed.preview=''{0}'' \u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u53EF\u80FD\u4F1A\u6210\u4E3A\u53D7\u9650\u7C7B\u578B\u540D\u79F0\uFF0C\u53EF\u80FD\u65E0\u6CD5\u7528\u4E8E\u7C7B\u578B\u58F0\u660E\uFF0C\u4E5F\u4E0D\u80FD\u7528\u4F5C\u6570\u7EC4\u7684\u5143\u7D20\u7C7B\u578B
# 0: name (variable), 1: message segment
compiler.err.cant.infer.local.var.type=\u65E0\u6CD5\u63A8\u65AD\u672C\u5730\u53D8\u91CF {0} \u7684\u7C7B\u578B\n({1})
-compiler.err.var.not.allowed.here=\u6B64\u5904\u4E0D\u5141\u8BB8\u4F7F\u7528 ''var''
-
-compiler.err.var.not.allowed.array=''var'' \u4E0D\u5141\u8BB8\u7528\u4F5C\u6570\u7EC4\u7684\u5143\u7D20\u7C7B\u578B
-
-compiler.err.var.not.allowed.compound=''var'' \u4E0D\u5141\u8BB8\u5728\u590D\u5408\u58F0\u660E\u4E2D\u4F7F\u7528
+# 0: name
+compiler.err.restricted.type.not.allowed.here=\u6B64\u5904\u4E0D\u5141\u8BB8\u4F7F\u7528 ''{0}''
+
+# 0: name
+compiler.err.restricted.type.not.allowed.array=''{0}'' \u4E0D\u5141\u8BB8\u7528\u4F5C\u6570\u7EC4\u7684\u5143\u7D20\u7C7B\u578B
+
+# 0: name
+compiler.err.restricted.type.not.allowed.compound=''{0}'' \u4E0D\u5141\u8BB8\u5728\u590D\u5408\u58F0\u660E\u4E2D\u4F7F\u7528
# 0: fragment
compiler.err.invalid.lambda.parameter.declaration=\u65E0\u6548\u7684 lambda \u53C2\u6570\u58F0\u660E\n({0})
@@ -1175,6 +1194,12 @@
# 0: number
compiler.misc.count.error.plural={0} \u4E2A\u9519\u8BEF
+# 0: number, 1: number
+compiler.misc.count.error.recompile=\u4EC5\u663E\u793A\u524D {0} \u4E2A\u9519\u8BEF\uFF08\u5171 {1} \u4E2A\uFF09\uFF1B\u82E5\u8981\u67E5\u770B\u66F4\u591A\u9519\u8BEF\uFF0C\u8BF7\u4F7F\u7528 -Xmaxerrs
+
+# 0: number, 1: number
+compiler.misc.count.warn.recompile=\u4EC5\u663E\u793A\u524D {0} \u4E2A\u8B66\u544A\uFF08\u5171 {1} \u4E2A\uFF09\uFF1B\u82E5\u8981\u67E5\u770B\u66F4\u591A\u9519\u8BEF\uFF0C\u8BF7\u4F7F\u7528 -Xmaxwarns
+
# 0: number
compiler.misc.count.warn={0} \u4E2A\u8B66\u544A
@@ -1370,6 +1395,15 @@
# 0: source version, 1: string, 2: string
compiler.warn.proc.processor.incompatible.source.version=\u6765\u81EA\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F ''{1}'' \u7684\u53D7\u652F\u6301 source \u7248\u672C ''{0}'' \u4F4E\u4E8E -source ''{2}''
+# 0: string, 1: string
+compiler.warn.proc.duplicate.option.name=\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F ''{1}'' \u8FD4\u56DE\u91CD\u590D\u7684\u652F\u6301\u7684\u9009\u9879 ''{0}''
+
+# 0: string, 1: string
+compiler.warn.proc.duplicate.supported.annotation=\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F ''{1}'' \u8FD4\u56DE\u91CD\u590D\u7684\u652F\u6301\u7684\u6CE8\u91CA\u7C7B\u578B ''{0}''
+
+# 0: string
+compiler.warn.proc.redundant.types.with.wildcard=\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F ''{0}'' \u91CD\u590D\u652F\u6301 ''*'' \u548C\u5176\u4ED6\u6CE8\u91CA\u7C7B\u578B
+
compiler.warn.proc.proc-only.requested.no.procs=\u5728\u672A\u8BF7\u6C42\u7F16\u8BD1\u7684\u60C5\u51B5\u4E0B\u8FDB\u884C\u6CE8\u91CA\u5904\u7406, \u4F46\u627E\u4E0D\u5230\u5904\u7406\u7A0B\u5E8F\u3002
compiler.warn.proc.use.implicit=\u6CE8\u91CA\u5904\u7406\u4E0D\u9002\u7528\u4E8E\u9690\u5F0F\u7F16\u8BD1\u7684\u6587\u4EF6\u3002\n\u4F7F\u7528 -implicit \u6307\u5B9A\u7528\u4E8E\u9690\u5F0F\u7F16\u8BD1\u7684\u7B56\u7565\u3002
@@ -1405,7 +1439,7 @@
compiler.warn.unchecked.cast.to.type=\u5411\u7C7B\u578B{0}\u7684\u8F6C\u6362\u672A\u7ECF\u8FC7\u68C0\u67E5
# 0: kind name, 1: name, 2: object, 3: object, 4: kind name, 5: symbol
-compiler.warn.unchecked.meth.invocation.applied=\u65B9\u6CD5\u8C03\u7528\u672A\u7ECF\u8FC7\u68C0\u67E5: \u5C06{4} {5}\u4E2D\u7684{0} {1}\u5E94\u7528\u5230\u7ED9\u5B9A\u7684\u7C7B\u578B\n\u9700\u8981: {2}\n\u627E\u5230: {3}
+compiler.warn.unchecked.meth.invocation.applied=\u65B9\u6CD5\u8C03\u7528\u672A\u7ECF\u8FC7\u68C0\u67E5: \u5C06{4} {5}\u4E2D\u7684{0} {1}\u5E94\u7528\u5230\u7ED9\u5B9A\u7684\u7C7B\u578B\n\u9700\u8981: {2}\n\u627E\u5230: {3}
# 0: type
compiler.warn.unchecked.generic.array.creation=\u5BF9\u4E8E\u7C7B\u578B\u4E3A{0}\u7684 varargs \u53C2\u6570, \u6CDB\u578B\u6570\u7EC4\u521B\u5EFA\u672A\u7ECF\u8FC7\u68C0\u67E5
@@ -1424,6 +1458,10 @@
# 0: string
compiler.warn.invalid.path=\u65E0\u6548\u6587\u4EF6\u540D: {0}
+# 0: string
+compiler.err.invalid.path=\u65E0\u6548\u6587\u4EF6\u540D: {0}
+
+
# 0: path
compiler.warn.invalid.archive.file=\u4EE5\u4E0B\u8DEF\u5F84\u4E2D\u5B58\u5728\u610F\u5916\u7684\u6587\u4EF6: {0}
@@ -1550,6 +1588,9 @@
# 0: file name, 1: string (expected constant pool entry type), 2: number (constant pool index)
compiler.misc.bad.const.pool.entry={0} \u4E2D\u9519\u8BEF\u7684\u5E38\u91CF\u6C60\u6761\u76EE\n\u9884\u671F\u4E3A\u7D22\u5F15 {2} \u5904\u7684 {1}
+# 0: file name, 1: number (constant pool index), 2: number (constant pool size)
+compiler.misc.bad.const.pool.index={0} \u4E2D\u7684\u5E38\u91CF\u6C60\u7D22\u5F15\u9519\u8BEF\n\u7D22\u5F15 {1} \u4E0D\u5728\u6C60\u5927\u5C0F {2} \u5185\u3002
+
# 0: file name, 1: message segment
compiler.misc.bad.class.file.header=\u9519\u8BEF\u7684\u7C7B\u6587\u4EF6: {0}\n{1}\n\u8BF7\u5220\u9664\u8BE5\u6587\u4EF6\u6216\u786E\u4FDD\u8BE5\u6587\u4EF6\u4F4D\u4E8E\u6B63\u786E\u7684\u7C7B\u8DEF\u5F84\u5B50\u76EE\u5F55\u4E2D\u3002
@@ -1876,17 +1917,6 @@
compiler.misc.kindname.instance.init=\u5B9E\u4F8B\u521D\u59CB\u5316\u7A0B\u5E8F
-# the following are names of tree kinds:
-compiler.misc.tree.tag.forloop=for
-
-compiler.misc.tree.tag.foreachloop=for
-
-compiler.misc.tree.tag.whileloop=while
-
-compiler.misc.tree.tag.doloop=do
-
-compiler.misc.tree.tag.switch=switch
-
#####
compiler.misc.no.args=\u6CA1\u6709\u53C2\u6570
@@ -2017,14 +2047,14 @@
compiler.misc.feature.private.intf.methods=\u79C1\u6709\u63A5\u53E3\u65B9\u6CD5
+compiler.misc.feature.text.blocks=\u6587\u672C\u5757
+
compiler.misc.feature.multiple.case.labels=\u591A\u4E2A case \u6807\u7B7E
compiler.misc.feature.switch.rules=switch \u89C4\u5219
compiler.misc.feature.switch.expressions=switch \u8868\u8FBE\u5F0F
-compiler.misc.feature.raw.string.literals=\u539F\u59CB\u5B57\u7B26\u4E32\u6587\u5B57
-
compiler.misc.feature.var.syntax.in.implicit.lambda=\u9690\u5F0F lambda \u4E2D\u7684 var \u8BED\u6CD5
compiler.warn.underscore.as.identifier=\u4ECE\u53D1\u884C\u7248 9 \u5F00\u59CB, ''_'' \u4E3A\u5173\u952E\u5B57, \u4E0D\u80FD\u7528\u4F5C\u6807\u8BC6\u7B26
@@ -2051,16 +2081,16 @@
compiler.err.cant.type.annotate.scoping=\u65E0\u6CD5\u4F7F\u7528 type-use \u6CE8\u91CA {0} \u6765\u6CE8\u91CA\u786E\u5B9A\u4F5C\u7528\u57DF\u7ED3\u6784
# 0: type, 1: type
-compiler.err.incorrect.receiver.name=\u63A5\u6536\u65B9\u540D\u79F0\u4E0E\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
+compiler.err.incorrect.receiver.name=\u63A5\u6536\u65B9\u540D\u79F0\u4E0E\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
# 0: type, 1: type
-compiler.err.incorrect.receiver.type=\u63A5\u6536\u65B9\u7C7B\u578B\u4E0E\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
+compiler.err.incorrect.receiver.type=\u63A5\u6536\u65B9\u7C7B\u578B\u4E0E\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
# 0: type, 1: type
-compiler.err.incorrect.constructor.receiver.type=\u63A5\u6536\u65B9\u7C7B\u578B\u4E0E\u5916\u90E8\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
+compiler.err.incorrect.constructor.receiver.type=\u63A5\u6536\u65B9\u7C7B\u578B\u4E0E\u5916\u90E8\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
# 0: type, 1: type
-compiler.err.incorrect.constructor.receiver.name=\u63A5\u6536\u65B9\u540D\u79F0\u4E0E\u5916\u90E8\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
+compiler.err.incorrect.constructor.receiver.name=\u63A5\u6536\u65B9\u540D\u79F0\u4E0E\u5916\u90E8\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1}
compiler.err.no.annotations.on.dot.class=\u7C7B\u6587\u5B57\u7C7B\u578B\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u4EFB\u4F55\u6CE8\u91CA
@@ -2331,7 +2361,7 @@
# 0: option name, 1: symbol
compiler.warn.module.for.option.not.found=\u627E\u4E0D\u5230 {0} \u9009\u9879\u4E2D\u7684\u6A21\u5757\u540D\u79F0: {1}
-compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH \u53EA\u80FD\u5728\u7F16\u8BD1\u672A\u547D\u540D\u6A21\u5757\u65F6\u4F7F\u7528
+compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH \u53EA\u80FD\u5728\u7F16\u8BD1\u672A\u547D\u540D\u6A21\u5757\u6216\u5728\u81EA\u52A8\u6A21\u5757\u7684\u4E0A\u4E0B\u6587\u4E2D\u7F16\u8BD1\u65F6\u4F7F\u7528
# 0: symbol
compiler.err.add.exports.with.release=\u4E0D\u5141\u8BB8\u5728\u4F7F\u7528 --release \u65F6\u4ECE\u7CFB\u7EDF\u6A21\u5757 {0} \u5BFC\u51FA\u7A0B\u5E8F\u5305:
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -52,9 +52,9 @@
javac.opt.J=<flag>\u3092\u5B9F\u884C\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059
javac.opt.encoding=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u4F7F\u7528\u3059\u308B\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3092\u6307\u5B9A\u3059\u308B
javac.opt.profile=\u4F7F\u7528\u3055\u308C\u3066\u3044\u308BAPI\u304C\u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3067\u4F7F\u7528\u53EF\u80FD\u304B\u3069\u3046\u304B\u3092\u78BA\u8A8D\u3057\u307E\u3059
-javac.opt.target=\u7279\u5B9A\u306EVM\u30D0\u30FC\u30B8\u30E7\u30F3\u7528\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3057\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30D0\u30FC\u30B8\u30E7\u30F3: {0}
-javac.opt.release=\u7279\u5B9A\u306E\u30EA\u30EA\u30FC\u30B9\u7528\u306B\u30B3\u30F3\u30D1\u30A4\u30EB\u3057\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30EA\u30EA\u30FC\u30B9: {0}
-javac.opt.source=\u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u4FDD\u6301\u3057\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30EA\u30EA\u30FC\u30B9: {0}
+javac.opt.target=\u6307\u5B9A\u3055\u308C\u305FJava SE\u30EA\u30EA\u30FC\u30B9\u306B\u9069\u3057\u305F\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3057\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30EA\u30EA\u30FC\u30B9: {0}
+javac.opt.release=\u6307\u5B9A\u3055\u308C\u305FJava SE\u30EA\u30EA\u30FC\u30B9\u306B\u5BFE\u3057\u3066\u30B3\u30F3\u30D1\u30A4\u30EB\u3057\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30EA\u30EA\u30FC\u30B9: {0}
+javac.opt.source=\u6307\u5B9A\u3055\u308C\u305FJava SE\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u4FDD\u6301\u3057\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30EA\u30EA\u30FC\u30B9: {0}
javac.opt.Werror=\u8B66\u544A\u304C\u767A\u751F\u3057\u305F\u5834\u5408\u306B\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7D42\u4E86\u3059\u308B
javac.opt.A=\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5\u306B\u6E21\u3055\u308C\u308B\u30AA\u30D7\u30B7\u30E7\u30F3
javac.opt.implicit=\u6697\u9ED9\u7684\u306B\u53C2\u7167\u3055\u308C\u308B\u30D5\u30A1\u30A4\u30EB\u306B\u3064\u3044\u3066\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B\u304B\u3069\u3046\u304B\u3092\u6307\u5B9A\u3059\u308B
@@ -146,6 +146,8 @@
javac.opt.Xlint.desc.static=\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u4F7F\u7528\u3057\u305Fstatic\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
+javac.opt.Xlint.desc.text-blocks=\u30C6\u30AD\u30B9\u30C8\u30FB\u30D6\u30ED\u30C3\u30AF\u30FB\u30A4\u30F3\u30C7\u30F3\u30C8\u5185\u306E\u4E00\u8CAB\u6027\u306E\u306A\u3044\u7A7A\u767D\u6587\u5B57\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
+
javac.opt.Xlint.desc.try=try\u30D6\u30ED\u30C3\u30AF(try-with-resources\u306A\u3069)\u306E\u4F7F\u7528\u306B\u95A2\u3059\u308B\u554F\u984C\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
javac.opt.Xlint.desc.unchecked=\u7121\u691C\u67FB\u64CD\u4F5C\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
@@ -202,7 +204,7 @@
javac.msg.usage.nonstandard.footer=\u3053\u306E\u8FFD\u52A0\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
-javac.msg.bug=\u30B3\u30F3\u30D1\u30A4\u30E9\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F({0})\u3002Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8(http://bugreport.java.com)\u3067Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3068\u4E0B\u8A18\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002
+javac.msg.bug=\u30B3\u30F3\u30D1\u30A4\u30E9\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F({0})\u3002Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8(http://bugreport.java.com)\u3067Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3001\u4E0B\u8A18\u306E\u8A3A\u65AD\u5185\u5BB9\u3001\u304A\u3088\u3073Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u6E21\u3057\u305F\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002
javac.msg.io=\n\n\u5165\u51FA\u529B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\n\u8A73\u7D30\u306F\u6B21\u306E\u30B9\u30BF\u30C3\u30AF\u30C8\u30EC\u30FC\u30B9\u3067\u8ABF\u67FB\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n
@@ -214,3 +216,7 @@
javac.version={0} {1}
javac.fullVersion={0}\u30D5\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3"{1}"
+
+javac.msg.parameters.output=javac\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u6B21\u306E\u5834\u6240\u306B\u51FA\u529B\u3057\u3066\u3044\u307E\u3059: {0}
+
+javac.msg.parameters.output.error=javac\u30D1\u30E9\u30E1\u30FC\u30BF\u3092{0}\u306B\u51FA\u529B\u3057\u3088\u3046\u3068\u3057\u305F\u3068\u304D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u7D9A\u304D\u307E\u3059:
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -52,9 +52,9 @@
javac.opt.J=\u76F4\u63A5\u5C06 <\u6807\u8BB0> \u4F20\u9012\u7ED9\u8FD0\u884C\u65F6\u7CFB\u7EDF
javac.opt.encoding=\u6307\u5B9A\u6E90\u6587\u4EF6\u4F7F\u7528\u7684\u5B57\u7B26\u7F16\u7801
javac.opt.profile=\u8BF7\u786E\u4FDD\u4F7F\u7528\u7684 API \u5728\u6307\u5B9A\u7684\u914D\u7F6E\u6587\u4EF6\u4E2D\u53EF\u7528
-javac.opt.target=\u751F\u6210\u9488\u5BF9\u7279\u5B9A VM \u7248\u672C\u7684\u7C7B\u6587\u4EF6\u3002\u652F\u6301\u7684\u7248\u672C\uFF1A{0}
-javac.opt.release=\u9488\u5BF9\u7279\u5B9A\u53D1\u884C\u7248\u8FDB\u884C\u7F16\u8BD1\u3002\u652F\u6301\u7684\u53D1\u884C\u7248\uFF1A{0}
-javac.opt.source=\u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\u3002\u652F\u6301\u7684\u53D1\u884C\u7248\uFF1A{0}
+javac.opt.target=\u751F\u6210\u9002\u5408\u6307\u5B9A\u7684 Java SE \u53D1\u884C\u7248\u7684\u7C7B\u6587\u4EF6\u3002\u652F\u6301\u7684\u53D1\u884C\u7248\uFF1A{0}
+javac.opt.release=\u4E3A\u6307\u5B9A\u7684 Java SE \u53D1\u884C\u7248\u7F16\u8BD1\u3002\u652F\u6301\u7684\u53D1\u884C\u7248\uFF1A{0}
+javac.opt.source=\u63D0\u4F9B\u4E0E\u6307\u5B9A\u7684 Java SE \u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\u3002\u652F\u6301\u7684\u53D1\u884C\u7248\uFF1A{0}
javac.opt.Werror=\u51FA\u73B0\u8B66\u544A\u65F6\u7EC8\u6B62\u7F16\u8BD1
javac.opt.A=\u4F20\u9012\u7ED9\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F\u7684\u9009\u9879
javac.opt.implicit=\u6307\u5B9A\u662F\u5426\u4E3A\u9690\u5F0F\u5F15\u7528\u6587\u4EF6\u751F\u6210\u7C7B\u6587\u4EF6
@@ -146,6 +146,8 @@
javac.opt.Xlint.desc.static=\u6709\u5173\u4F7F\u7528\u5B9E\u4F8B\u6765\u8BBF\u95EE\u9759\u6001\u6210\u5458\u7684\u8B66\u544A\u3002
+javac.opt.Xlint.desc.text-blocks=\u6709\u5173\u6587\u672C\u5757\u7F29\u8FDB\u4E2D\u7684\u7A7A\u683C\u5B57\u7B26\u4E0D\u4E00\u81F4\u7684\u8B66\u544A\u3002
+
javac.opt.Xlint.desc.try=\u6709\u5173\u4E0E\u4F7F\u7528 try \u5757 (\u4F8B\u5982 try-with-resources) \u76F8\u5173\u7684\u95EE\u9898\u7684\u8B66\u544A\u3002
javac.opt.Xlint.desc.unchecked=\u6709\u5173\u672A\u68C0\u67E5\u64CD\u4F5C\u7684\u8B66\u544A\u3002
@@ -202,7 +204,7 @@
javac.msg.usage.nonstandard.footer=\u8FD9\u4E9B\u989D\u5916\u9009\u9879\u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002
-javac.msg.bug=\u7F16\u8BD1\u5668 ({0}) \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF, \u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u5EFA\u7ACB\u8BE5 Java \u7F16\u8BD1\u5668 Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002
+javac.msg.bug=\u7F16\u8BD1\u5668 ({0}) \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF\uFF0C\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u5EFA\u7ACB\u8BE5 Java \u7F16\u8BD1\u5668 Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u3001\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u4EE5\u53CA\u4F20\u9012\u5230 Java \u7F16\u8BD1\u5668\u7684\u53C2\u6570\u3002\u8C22\u8C22\u3002
javac.msg.io=\n\n\u53D1\u751F\u8F93\u5165/\u8F93\u51FA\u9519\u8BEF\u3002\n\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u53C2\u9605\u4EE5\u4E0B\u5806\u6808\u8DDF\u8E2A\u3002\n
@@ -214,3 +216,7 @@
javac.version={0} {1}
javac.fullVersion={0}\u5B8C\u6574\u7248\u672C "{1}"
+
+javac.msg.parameters.output=\u6B63\u5728\u5C06 javac \u53C2\u6570\u6253\u5370\u5230\uFF1A{0}
+
+javac.msg.parameters.output.error=\u5C1D\u8BD5\u5C06 javac \u53C2\u6570\u6253\u5370\u5230 {0} \u65F6\u51FA\u9519\uFF0C\u53C2\u6570\u5C06\u91C7\u7528\uFF1A
--- a/src/jdk.compiler/share/man/javac.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.compiler/share/man/javac.1 Mon Jul 22 11:08:27 2019 +0530
@@ -21,147 +21,140 @@
.\"
.\" Automatically generated by Pandoc 2.3.1
.\"
-.TH "JAVAC" "1" "2018" "JDK 13" "JDK Commands"
+.TH "JAVAC" "1" "2019" "JDK 13" "JDK Commands"
.hy
.SH NAME
.PP
-javac \- read Java class and interface definitions and compile them into
-bytecode and class files
+javac \- read Java declarations and compile them into class files
.SH SYNOPSIS
.PP
-\f[CB]javac\f[R] [\f[I]options\f[R]] [\f[I]sourcefiles\f[R]]
+\f[CB]javac\f[R] [\f[I]options\f[R]] [\f[I]sourcefiles\-or\-classnames\f[R]]
.TP
.B \f[I]options\f[R]
Command\-line options.
-See \f[B]Overview of javac Options\f[R].
.RS
.RE
.TP
-.B \f[I]sourcefiles\f[R]
-One or more source files to be compiled (such as \f[CB]MyClass.java\f[R])
-or processed for annotations (such as \f[CB]MyPackage.MyClass\f[R]).
+.B \f[I]sourcefiles\-or\-classnames\f[R]
+Source files to be compiled (for example, \f[CB]Shape.java\f[R]) or the
+names of previously compiled classes to be processed for annotations
+(for example, \f[CB]geometry.MyShape\f[R]).
.RS
.RE
.SH DESCRIPTION
.PP
-The \f[CB]javac\f[R] command reads class and interface definitions,
-written in the Java programming language, and compiles them into
-bytecode class files.
-The \f[CB]javac\f[R] command can also process annotations in Java source
-files and classes.
+The \f[CB]javac\f[R] command reads \f[I]source files\f[R] that contain
+module, package and type declarations written in the Java programming
+language, and compiles them into \f[I]class files\f[R] that run on the
+Java Virtual Machine.
+.PP
+The \f[CB]javac\f[R] command can also \f[B]process annotations\f[R] in Java
+source files and classes.
.PP
-A new launcher environment variable, \f[CB]JDK_JAVAC_OPTIONS\f[R], was
-introduced in JDK 9 that prepended its content to the command line to
-\f[CB]javac\f[R] .
-See \f[B]Using JDK_JAVAC_OPTIONS Environment Variable\f[R].
+Source files must have a file name extension of \f[CB]\&.java\f[R].
+Class files have a file name extension of \f[CB]\&.class\f[R].
+Both source and class files normally have file names that identify the
+contents.
+For example, a class called \f[CB]Shape\f[R] would be declared in a source
+file called \f[CB]Shape.java\f[R], and compiled into a class file called
+\f[CB]Shape.class\f[R].
.PP
-There are two ways to pass source code file names to \f[CB]javac\f[R].
+There are two ways to specify source files to \f[CB]javac\f[R]:
.IP \[bu] 2
-For a small number of source files, you can list the file names on the
+For a small number of source files, you can list their file names on the
command line.
.IP \[bu] 2
For a large number of source files, you can use the
-\f[CB]\@\f[R]\f[I]filename\f[R] option on the \f[CB]javac\f[R] command line
-to include a file that lists the source file names.
+\f[CB]\@\f[R]\f[I]filename\f[R] option on the command line to specify an
+\f[I]argument file\f[R] that lists their file names.
See \f[B]Standard Options\f[R] for a description of the option and
-\f[B]javac Command\-Line Argument Files\f[R] for a description of
+\f[B]Command\-Line Argument Files\f[R] for a description of
\f[CB]javac\f[R] argument files.
.PP
-Source code file names must have \f[CB]\&.java\f[R] suffixes, class file
-names must have \f[CB]\&.class\f[R] suffixes, and both source and class
-files must have root names that identify the class.
-For example, a class called \f[CB]MyClass\f[R] would be written in a
-source file called \f[CB]MyClass.java\f[R] and compiled into a bytecode
-class file called \f[CB]MyClass.class\f[R].
+The order of source files specified on the command line or in an
+argument file is not important.
+\f[CB]javac\f[R] will compile the files together, as a group, and will
+automatically resolve any dependencies between the declarations in the
+various source files.
.PP
-Inner class definitions produce additional class files.
-These class files have names that combine the inner and outer class
-names, such as \f[CB]MyClass$MyInnerClass.class\f[R].
+\f[CB]javac\f[R] expects that source files are arranged in one or more
+directory hierarchies on the file system, described in \f[B]Arrangement
+of Source Code\f[R].
.PP
-You should arrange the source files in a directory tree that reflects
-their package tree.
-For example:
-.IP \[bu] 2
-\f[B]Oracle Solaris, Linux, and OS X:\f[R] If all of your source files
-are in \f[CB]/workspace\f[R], then put the source code for
-\f[CB]com.mysoft.mypack.MyClass\f[R] in
-\f[CB]/workspace/com/mysoft/mypack/MyClass.java\f[R].
-.IP \[bu] 2
-\f[B]Windows:\f[R] If all of your source files are in
-\f[CB]\\workspace\f[R], then put the source code for
-\f[CB]com.mysoft.mypack.MyClass\f[R] in
-\f[CB]\\workspace\\com\\mysoft\\mypack\\MyClass.java\f[R].
+To compile a source file, \f[CB]javac\f[R] needs to find the declaration
+of every class or interface that is used, extended, or implemented by
+the code in the source file.
+This lets \f[CB]javac\f[R] check that the code has the right to access
+those classes and interfaces.
+Rather than specifying the source files of those classes and interfaces
+explicitly, you can use command\-line options to tell \f[CB]javac\f[R]
+where to search for their source files.
+If you have compiled those source files previously, you can use options
+to tell \f[CB]javac\f[R] where to search for the corresponding class
+files.
+The options, which all have names ending in "path", are described in
+\f[B]Standard Options\f[R], and further described in \f[B]Configuring a
+Compilation\f[R] and \f[B]Searching for Module, Package and Type
+Declarations\f[R].
.PP
-By default, the compiler puts each class file in the same directory as
-its source file.
-You can specify a separate destination directory with the \f[CB]\-d\f[R]
-option described in \f[B]Standard Options\f[R].
-.SH PROGRAMMATIC INTERFACE
-.PP
-The \f[CB]javac\f[R] command supports the new Java Compiler API defined by
-the classes and interfaces in the \f[CB]javax.tools\f[R] package.
-.SH IMPLICITLY LOADED SOURCE FILES
-.PP
-To compile a set of source files, the compiler might need to implicitly
-load additional source files.
-See \f[B]Searching for Types\f[R].
-Such files are currently not subject to annotation processing.
-By default, the compiler gives a warning when annotation processing
-occurs and any implicitly loaded source files are compiled.
-The \f[CB]\-implicit\f[R] option provides a way to suppress the warning.
-.SH USING JDK_JAVAC_OPTIONS ENVIRONMENT VARIABLE
+By default, \f[CB]javac\f[R] compiles each source file to a class file in
+the same directory as the source file.
+However, it is recommended to specify a separate destination directory
+with the \f[CB]\-d\f[R] option described in \f[B]Standard Options\f[R].
.PP
-The content of the \f[CB]JDK_JAVAC_OPTIONS\f[R] environment variable,
-separated by white\-spaces ( ) or white\-space characters (\f[CB]\\n\f[R],
-\f[CB]\\t\f[R], \f[CB]\\r\f[R], or \f[CB]\\f\f[R]) is prepended to the command
-line arguments passed to \f[CB]javac\f[R] as a list of arguments.
-.PP
-The encoding requirement for the environment variable is the same as the
-\f[CB]javac\f[R] command line on the system.
-\f[CB]JDK_JAVAC_OPTIONS\f[R] environment variable content is treated in
-the same manner as that specified in the command line.
+Command\-line \f[B]options\f[R] and \f[B]environment variables\f[R] also
+control how \f[CB]javac\f[R] performs various tasks:
+.IP \[bu] 2
+Compiling code to run on earlier releases of the JDK.
+.IP \[bu] 2
+Compiling code to run under a debugger.
+.IP \[bu] 2
+Checking for stylistic issues in Java source code.
+.IP \[bu] 2
+Checking for problems in \f[CB]javadoc\f[R] comments
+(\f[CB]/**\ ...\ */\f[R]).
+.IP \[bu] 2
+Processing annotations in source files and class files.
+.IP \[bu] 2
+Upgrading and patching modules in the compile\-time environment.
.PP
-Single quotes (\f[CB]\[aq]\f[R]) or double quotes (\f[CB]"\f[R]) can be used
-to enclose arguments that\ contain whitespace characters.
-All content between the open quote and the first matching close quote
-are preserved by simply removing the pair of quotes.
-In case a matching quote is not found, the launcher will abort with an
-error message.
-\f[CB]\@\f[R]\f[I]files\f[R] are supported as they are specified in the
-command line.
-However, as in \f[CB]\@\f[R]\f[I]files\f[R], use of a wildcard is not
-supported.
+\f[CB]javac\f[R] supports \f[B]Compiling for Earlier Releases Of The
+Platform\f[R] and can also be invoked from Java code using one of a
+number of \f[B]APIs\f[R]
+.SH OPTIONS
.PP
-\f[B]Examples of quoting arguments containing white spaces:\f[R]
-.RS
+\f[CB]javac\f[R] provides \f[B]standard options\f[R], and \f[B]extra
+options\f[R] that are either non\-standard or are for advanced use.
.PP
-\f[CB]export\ JDK_JAVAC_OPTIONS=\[aq]\@"C:\\white\ spaces\\argfile"\[aq]\f[R]
-.RE
-.RS
-.PP
-\f[CB]export\ JDK_JAVAC_OPTIONS=\[aq]"\@C:\\white\ spaces\\argfile"\[aq]\f[R]
-.RE
-.RS
-.PP
-\f[CB]export\ JDK_JAVAC_OPTIONS=\[aq]\@C:\\"white\ spaces"\\argfile\[aq]\f[R]
-.RE
-.SH OVERVIEW OF JAVAC OPTIONS
+Some options take one or more arguments.
+If an argument contains spaces or other whitespace characters, the value
+should be quoted according to the conventions of the environment being
+used to invoke javac.
+If the option begins with a single dash (\f[CB]\-\f[R]) the argument
+should either directly follow the option name, or should be separated
+with a colon (\f[CB]:\f[R]) or whitespace, depending on the option.
+If the option begins with a double dash (\f[CB]\-\-\f[R]), the argument
+may be separated either by whitespace or by an equals (\f[CB]=\f[R])
+character with no additional whitespace.
+For example,
+.IP
+.nf
+\f[CB]
+\-Aname="J.\ Duke"
+\-proc:only
+\-d\ myDirectory
+\-\-module\-version\ 3
+\-\-module\-version=3
+\f[R]
+.fi
.PP
-The compiler has sets of standard options, and cross\-compilation
-options that are supported on the current development environment.
-The compiler also has a set of nonstandard options that are specific to
-the current virtual machine and compiler implementations but are subject
-to change in the future.
-The nonstandard options begin with \f[CB]\-X\f[R] .
-The different sets of \f[CB]javac\f[R] options are described in the
-following sections:
-.IP \[bu] 2
-\f[B]Standard Options\f[R]
-.IP \[bu] 2
-\f[B]Cross\-Compilation Options for javac\f[R]
-.IP \[bu] 2
-\f[B]Extra Options\f[R]
-.SH STANDARD OPTIONS
+In the following lists of options, an argument of \f[I]path\f[R]
+represents a search path, composed of a list of file system locations
+separated by the platform path separator character, (semicolon
+\f[CB];\f[R] on Windows, or colon \f[CB]:\f[R] on other systems.) Depending
+on the option, the file system locations may be directories, JAR files
+or JMOD files.
+.SS Standard Options
.TP
.B \f[CB]\@\f[R]\f[I]filename\f[R]
Reads options and file names from a file.
@@ -170,13 +163,13 @@
(except \f[CB]\-J\f[R] options).
This lets you to create \f[CB]javac\f[R] commands of any length on any
operating system.
-See \f[B]javac Command\-Line Argument Files\f[R].
+See \f[B]Command\-Line Argument Files\f[R].
.RS
.RE
.TP
.B \f[CB]\-A\f[R]\f[I]key\f[R][\f[CB]=\f[R]\f[I]value\f[R]]
Specifies options to pass to annotation processors.
-These options aren\[aq]t interpreted by \f[CB]javac\f[R] directly, but are
+These options are not interpreted by \f[CB]javac\f[R] directly, but are
made available for use by individual processors.
The \f[I]key\f[R] value should be one or more identifiers separated by a
dot (\f[CB]\&.\f[R]).
@@ -194,11 +187,11 @@
Overrides the location of the bootstrap class files.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
+For JDK 9 or later, see \f[CB]\-\-system\f[R].
.RE
.TP
.B \f[CB]\-\-class\-path\f[R] \f[I]path\f[R], \f[CB]\-classpath\f[R] \f[I]path\f[R], or \f[CB]\-cp\f[R] \f[I]path\f[R]
@@ -207,41 +200,48 @@
environment variable.
.RS
.IP \[bu] 2
-If \f[CB]\-\-class\-path\f[R], \f[CB]\-classpath\f[R], or \f[CB]\-cp\f[R]
-aren\[aq]t specified, then the user class path is the current directory.
+If \f[CB]\-\-class\-path\f[R], \f[CB]\-classpath\f[R], or \f[CB]\-cp\f[R] are
+not specified, then the user class path is the value of the
+\f[CB]CLASSPATH\f[R] environment variable, if that is set, or else the
+current directory.
.IP \[bu] 2
-If the \f[CB]\-sourcepath\f[R] option isn\[aq]t specified, then the user
-class path is also searched for source files.
+If not compiling code for modules, if the \f[CB]\-\-source\-path\f[R] or
+\-sourcepath` option is not specified, then the user class path is also
+searched for source files.
.IP \[bu] 2
-If the \f[CB]\-processorpath\f[R] option isn\[aq]t specified, then the
-class path is also searched for annotation processors.
+If the \f[CB]\-processorpath\f[R] option is not specified, then the class
+path is also searched for annotation processors.
.RE
.TP
.B \f[CB]\-d\f[R] \f[I]directory\f[R]
-Sets the destination directory for class files.
+Sets the destination directory (or \f[I]class output directory\f[R]) for
+class files.
If a class is part of a package, then \f[CB]javac\f[R] puts the class file
-in a subdirectory that reflects the package name and creates directories
-as needed.
-For example:
+in a subdirectory that reflects the module name (if appropriate) and
+package name.
+The directory, and any necessary subdirectories, will be created if they
+do not already exist.
.RS
-.IP \[bu] 2
-\f[B]Oracle Solaris, Linux, and OS X:\f[R] If you specify
-\f[CB]\-d\ /home/myclasses\f[R] and the class is called
-\f[CB]com.mypackage.MyClass\f[R], then the class file is
-\f[CB]/home/myclasses/com/mypackage/MyClass.class\f[R].
-.IP \[bu] 2
-\f[B]Windows:\f[R] If you specify \f[CB]\-d\ C:\\myclasses\f[R] and the
-class is called \f[CB]com.mypackage.MyClass\f[R], then the class file is
-\f[CB]C:\\myclasses\\com\\mypackage\\MyClass.class\f[R].
.PP
-If the \f[CB]\-d\f[R] option isn\[aq]t specified, then \f[CB]javac\f[R] puts
+If the \f[CB]\-d\f[R] option is not specified, then \f[CB]javac\f[R] puts
each class file in the same directory as the source file from which it
was generated.
.PP
-\f[B]Note:\f[R]
+Except when compiling code for multiple modules, the contents of the
+class output directory will be organized in a package hierarchy.
+When compiling code for multiple modules, the contents of the output
+directory will be organized in a module hierarchy, with the contents of
+each module in a separate subdirectory, each organized as a package
+hierarchy.
.PP
-The directory specified by the \f[CB]\-d\f[R] option isn\[aq]t
-automatically added to your user class path.
+\f[B]Note:\f[R] When compiling code for one or more modules, the class
+output directory will automatically be checked when searching for
+previously compiled classes.
+When not compiling for modules, for backwards compatibility, the
+directory is \f[I]not\f[R] automatically checked for previously compiled
+classes, and so it is recommended to specify the class output directory
+as one of the locations on the user class path, using the
+\f[CB]\-\-class\-path\f[R] option or one of its alternate forms.
.RE
.TP
.B \f[CB]\-deprecation\f[R]
@@ -265,7 +265,7 @@
.B \f[CB]\-encoding\f[R] \f[I]encoding\f[R]
Specifies character encoding used by source files, such as EUC\-JP and
UTF\-8.
-If the \f[CB]\-encoding\f[R] option isn\[aq]t specified, then the platform
+If the \f[CB]\-encoding\f[R] option is not specified, then the platform
default converter is used.
.RS
.RE
@@ -274,30 +274,29 @@
Overrides the location of the endorsed standards path.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-extdirs\f[R] \f[I]directories\f[R]
Overrides the location of the installed extensions.
-The \f[CB]directories\f[R] variable is a colon\-separated list of
-directories.
+\f[CB]directories\f[R] is a list of directories, separated by the platform
+path separator (\f[CB];\f[R] on Windows, and \f[CB]:\f[R] otherwise).
Each JAR file in the specified directories is searched for class files.
All JAR files found become part of the class path.
.RS
.PP
-If you are cross\-compiling, then this option specifies the directories
-that contain the extension classes.
-See \f[B]Cross\-Compilation Options for javac\f[R].
+If you are compiling for a release of the platform that supports the
+Extension Mechanism, then this option specifies the directories that
+contain the extension classes.
+See [Compiling for Other Releases of the Platform].
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-g\f[R]
@@ -329,22 +328,23 @@
.RE
.TP
.B \f[CB]\-g:none\f[R]
-Doesn\[aq]t generate debugging information.
+Does not generate debugging information.
.RS
.RE
.TP
.B \f[CB]\-h\f[R] \f[I]directory\f[R]
-Specfies where to place generated native header files.
+Specifies where to place generated native header files.
.RS
.PP
When you specify this option, a native header file is generated for each
class that contains native methods or that has one or more constants
annotated with the \f[B]\f[BC]java.lang.annotation.Native\f[B]\f[R]
-[https://docs.oracle.com/javase/10/docs/api/java/lang/annotation/Native.html]
annotation.
If the class is part of a package, then the compiler puts the native
-header file in a subdirectory that reflects the package name and creates
-directories as needed.
+header file in a subdirectory that reflects the module name (if
+appropriate) and package name.
+The directory, and any necessary subdirectories, will be created if they
+do not already exist.
.RE
.TP
.B \f[CB]\-\-help\f[R], \f[CB]\-help\f[R] or \f[CB]\-?\f[R]
@@ -353,7 +353,7 @@
.RE
.TP
.B \f[CB]\-\-help\-extra\f[R] or \f[CB]\-X\f[R]
-Prints the help for extra options.
+Prints a synopsis of the set of extra options.
.RS
.RE
.TP
@@ -366,13 +366,13 @@
.IP \[bu] 2
\f[CB]\-implicit:none\f[R] \-\-\- Suppresses class file generation.
.PP
-If this option isn\[aq]t specified, then the default automatically
+If this option is not specified, then the default automatically
generates class files.
In this case, the compiler issues a warning if any class files are
generated when also doing annotation processing.
-The warning isn\[aq]t issued when the \f[CB]\-implicit\f[R] option is
+The warning is not issued when the \f[CB]\-implicit\f[R] option is
explicitly set.
-See \f[B]Searching for Types\f[R].
+See \f[B]Searching for Module, Package and Type Declarations\f[R].
.RE
.TP
.B \f[CB]\-J\f[R]\f[I]option\f[R]
@@ -381,14 +381,13 @@
For example, \f[CB]\-J\-Xms48m\f[R] sets the startup memory to 48 MB.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-The \f[CB]CLASSPATH\f[R] environment variable, \f[CB]\-classpath\f[R]
-option, \f[CB]\-bootclasspath\f[R] option, and \f[CB]\-extdirs\f[R] option
-don\[aq]t specify the classes used to run \f[CB]javac\f[R].
+\f[B]Note:\f[R] The \f[CB]CLASSPATH\f[R] environment variable,
+\f[CB]\-classpath\f[R] option, \f[CB]\-bootclasspath\f[R] option, and
+\f[CB]\-extdirs\f[R] option do not specify the classes used to run
+\f[CB]javac\f[R].
Trying to customize the compiler implementation with these options and
-variables is risky and often doesn\[aq]t accomplish what you want.
-If you must customize the complier implementation, then use the
+variables is risky and often does not accomplish what you want.
+If you must customize the compiler implementation, then use the
\f[CB]\-J\f[R] option to pass options through to the underlying Java
launcher.
.RE
@@ -398,8 +397,9 @@
.RS
.RE
.TP
-.B \f[CB]\-\-module\f[R] \f[I]module\-name\f[R] or \f[CB]\-m\f[R] \f[I]module\-name\f[R]
-Compiles only the specified module and checks time stamps.
+.B \f[CB]\-\-module\f[R] \f[I]module\-name\f[R] (\f[CB],\f[R]\f[I]module\-name\f[R])* or \f[CB]\-m\f[R] \f[I]module\-name\f[R] (\f[CB],\f[R]\f[I]module\-name\f[R])*
+Compiles those source files in the named modules that are newer than the
+corresponding files in the output directory.
.RS
.RE
.TP
@@ -409,7 +409,9 @@
.RE
.TP
.B \f[CB]\-\-module\-source\-path\f[R] \f[I]module\-source\-path\f[R]
-Specifies where to find input source files for multiple modules.
+Specifies where to find source files when compiling code in multiple
+modules.
+See [Compilation Modes] and \f[B]The Module Source Path Option\f[R].
.RS
.RE
.TP
@@ -455,7 +457,7 @@
.TP
.B \f[CB]\-\-processor\-path\f[R] \f[I]path\f[R] or \f[CB]\-processorpath\f[R] \f[I]path\f[R]
Specifies where to find annotation processors.
-If this option isn\[aq]t used, then the class path is searched for
+If this option is not used, then the class path is searched for
processors.
.RS
.RE
@@ -464,63 +466,67 @@
Checks that the API used is available in the specified profile.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-\-release\f[R] \f[I]release\f[R]
Compiles source code according to the rules of the Java programming
-language for the specified Java SE release, generating class files
-suitable for that release.
-Additionally, compiles source code against the API of the specified Java
-SE release and the API supported by the corresponding JDK release.
-The supported values of \f[I]release\f[R] are the current Java SE release
-and a limited number of previous releases.
-The exact set of supported values is given in the command\-line help.
+language for the specified Java SE release, generating class files which
+target that release.
+Source code is compiled against the combined Java SE and JDK API for the
+specified release.
.RS
.PP
-The API of a Java SE release consists of the \f[CB]java.*\f[R],
-\f[CB]javax.*\f[R], and \f[CB]org.*\f[R] packages that are exported by Java
-SE modules in the release.
+The supported values of \f[I]release\f[R] are the current Java SE release
+and a limited number of previous releases, detailed in the command\-line
+help.
+.PP
+For the current release, the Java SE API consists of the
+\f[CB]java.*\f[R], \f[CB]javax.*\f[R], and \f[CB]org.*\f[R] packages that are
+exported by the Java SE modules in the release; the JDK API consists of
+the \f[CB]com.*\f[R] and \f[CB]jdk.*\f[R] packages that are exported by the
+JDK modules in the release, plus the \f[CB]javax.*\f[R] packages that are
+exported by standard, but non\-Java SE, modules in the release.
.PP
-The API supported by a JDK release consists of the \f[CB]com.*\f[R] and
-\f[CB]jdk.*\f[R] packages that are exported by JDK modules in the release,
-plus the \f[CB]javax.*\f[R] packages that are exported by standard, but
-non\-Java SE, modules in the release.
+For previous releases, the Java SE API and the JDK API are as defined in
+that release.
.PP
-\f[B]Note:\f[R]
+\f[B]Note:\f[R] When using \f[CB]\-\-release\f[R], you cannot also use the
+\f[CB]\-\-source\f[R]/\f[CB]\-source\f[R] or
+\f[CB]\-\-target\f[R]/\f[CB]\-target\f[R] options.
.PP
-The \f[CB]\-\-add\-exports\f[R] option cannot be used to enlarge the set
-of packages exported by the Java SE and JDK API.
+\f[B]Note:\f[R] When using \f[CB]\-\-release\f[R] to specify a release that
+supports the Java Platform Module System, the \f[CB]\-\-add\-exports\f[R]
+option cannot be used to enlarge the set of packages exported by the
+Java SE, JDK, and standard modules in the specified release.
.RE
.TP
.B \f[CB]\-s\f[R] \f[I]directory\f[R]
Specifies the directory used to place the generated source files.
If a class is part of a package, then the compiler puts the source file
-in a subdirectory that reflects the package name and creates directories
-as needed.
-For example:
+in a subdirectory that reflects the module name (if appropriate) and
+package name.
+The directory, and any necessary subdirectories, will be created if they
+do not already exist.
.RS
-.IP \[bu] 2
-\f[B]Oracle Solaris, Linux, and OS X:\f[R] If you specify
-\f[CB]\-s\ /home/mysrc\f[R] and the class is called
-\f[CB]com.mypackage.MyClass\f[R], then the source file is put in
-\f[CB]/home/mysrc/com/mypackage/MyClass.java\f[R].
-.IP \[bu] 2
-\f[B]Windows:\f[R] If you specify \f[CB]\-s\ C:\\mysrc\f[R] and the class
-is called \f[CB]com.mypackage.MyClass\f[R], then the source file is put in
-\f[CB]C:\\mysrc\\com\\mypackage\\MyClass.java\f[R].
+.PP
+Except when compiling code for multiple modules, the contents of the
+source output directory will be organized in a package hierarchy.
+When compiling code for multiple modules, the contents of the source
+output directory will be organized in a module hierarchy, with the
+contents of each module in a separate subdirectory, each organized as a
+package hierarchy.
.RE
.TP
.B \f[CB]\-\-source\f[R] \f[I]release\f[R] or \f[CB]\-source\f[R] \f[I]release\f[R]
Compiles source code according to the rules of the Java programming
language for the specified Java SE release.
The supported values of \f[I]release\f[R] are the current Java SE release
-and a limited number of previous releases.
-The exact set of supported values is given in the command\-line help.
+and a limited number of previous releases, detailed in the command\-line
+help.
.RS
.PP
If the option is not specified, the default is to compile source code
@@ -529,21 +535,14 @@
.RE
.TP
.B \f[CB]\-\-source\-path\f[R] \f[I]path\f[R] or \f[CB]\-sourcepath\f[R] \f[I]path\f[R]
-Specifies where to find input source files.
-This is the source code path used to search for class or interface
-definitions.
-As with the user class path, source path entries are separated by colons
-(\f[CB]:\f[R]) on Oracle Solaris and semicolons (\f[CB];\f[R]) on Windows.
-They can be directories, JAR archives, or ZIP archives.
-If packages are used, then the local path name within the directory or
-archive must reflect the package name.
+Specifies where to find source files.
+Except when compiling multiple modules together, this is the source code
+path used to search for class or interface definitions.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-Classes found through the class path might be recompiled when their
-source files are also found.
-See \f[B]Searching for Types\f[R].
+\f[B]Note:\f[R] Classes found through the class path might be recompiled
+when their source files are also found.
+See \f[B]Searching for Module, Package and Type Declarations\f[R].
.RE
.TP
.B \f[CB]\-\-system\f[R] \f[I]jdk\f[R] | \f[CB]none\f[R]
@@ -555,15 +554,13 @@
Generates \f[CB]class\f[R] files suitable for the specified Java SE
release.
The supported values of \f[I]release\f[R] are the current Java SE release
-and a limited number of previous releases.
-The exact set of supported values is given in the command\-line help.
+and a limited number of previous releases, detailed in the command\-line
+help.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-It is an error to specify a value for \f[I]release\f[R] that is lower
-than the the release for which the source code is being compiled.
-(See \f[CB]\-\-source\f[R]).
+\f[B]Note:\f[R] The target release must be equal to or higher than the
+source release.
+(See \f[CB]\-\-source\f[R].)
.RE
.TP
.B \f[CB]\-\-upgrade\-module\-path\f[R] \f[I]path\f[R]
@@ -587,23 +584,7 @@
Terminates compilation when warnings occur.
.RS
.RE
-.SH CROSS\-COMPILATION OPTIONS FOR JAVAC
-.PP
-By default, for releases prior to JDK 9, classes were compiled against
-the bootstrap classes of the platform that shipped with
-the\f[CB]javac\f[R] command.
-But \f[CB]javac\f[R] also supports cross\-compiling, in which classes are
-compiled against bootstrap classes of a different Java platform
-implementation.
-It\[aq]s important to use the \f[CB]\-bootclasspath\f[R] and
-\f[CB]\-extdirs\f[R] options when cross\-compiling.
-.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
-.SH EXTRA OPTIONS
+.SS Extra Options
.TP
.B \f[CB]\-\-add\-exports\f[R] \f[I]module\f[R]\f[CB]/\f[R]\f[I]package\f[R]\f[CB]=\f[R]\f[I]other\-module\f[R](\f[CB],\f[R]\f[I]other\-module\f[R])*
Specifies a package to be considered as exported from its defining
@@ -628,22 +609,20 @@
Overrides the location of the endorsed standards path.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-Djava.ext.dirs=\f[R]\f[I]dirs\f[R]
Overrides the location of installed extensions.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-\-doclint\-format\f[R] [\f[CB]html4\f[R]|\f[CB]html5\f[R]]
@@ -651,7 +630,7 @@
.RS
.RE
.TP
-.B \f[CB]\-\-patch\-module\f[R] \f[I]module\f[R]\f[CB]=\f[R]\f[I]file\f[R](\f[CB]:\f[R]\f[I]file\f[R])*
+.B \f[CB]\-\-patch\-module\f[R] \f[I]module\f[R]\f[CB]=\f[R]\f[I]path\f[R]
Overrides or augments a module with classes and resources in JAR files
or directories.
.RS
@@ -661,33 +640,30 @@
Overrides the location of the bootstrap class files.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-Xbootclasspath/a:\f[R]\f[I]path\f[R]
Adds a suffix to the bootstrap class path.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-Xbootclasspath/p:\f[R]\f[I]path\f[R]
Adds a prefix to the bootstrap class path.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-This can only be used when compiling for versions prior to JDK 9.
-As applicable, see the descriptions in\ \f[CB]\-\-release\f[R],
-\f[CB]\-source\f[R], or \f[CB]\-target\f[R]\ for details.
+\f[B]Note:\f[R] This can only be used when compiling for releases prior
+to JDK 9.
+As applicable, see the descriptions in \f[CB]\-\-release\f[R],
+\f[CB]\-source\f[R], or \f[CB]\-target\f[R] for details.
.RE
.TP
.B \f[CB]\-Xdiags:\f[R][\f[CB]compact\f[R], \f[CB]verbose\f[R]]
@@ -745,7 +721,7 @@
.RE
.PP
The following option enables all groups of checks for all access levels,
-except it won\[aq]t check for HTML errors for classes and members that
+except it will not check for HTML errors for classes and members that
have the access level of package and higher (which includes package,
protected and public):
.RS
@@ -802,7 +778,7 @@
\f[CB]fallthrough\f[R]: Warns about the falling through from one case of a
switch statement to the next.
.IP \[bu] 2
-\f[CB]finally\f[R]: Warns about \f[CB]finally\f[R] clauses that don\[aq]t
+\f[CB]finally\f[R]: Warns about \f[CB]finally\f[R] clauses that do not
terminate normally.
.IP \[bu] 2
\f[CB]module\f[R]: Warns about the module system\-related issues.
@@ -833,7 +809,7 @@
\f[CB]requires\-transitive\-automatic\f[R]: Warns about automatic modules
in requires transitive.
.IP \[bu] 2
-\f[CB]serial\f[R]: Warns about the serializable classes that don\[aq]t
+\f[CB]serial\f[R]: Warns about the serializable classes that do not
provide a serial version ID.
Also warns about access to non\-public members from a serializable
element.
@@ -882,15 +858,13 @@
.B \f[CB]legacy\f[R]
Generates a \f[CB]package\-info.class\f[R] file only if
\f[CB]package\-info.java\f[R] contains annotations.
-This option doesn\[aq]t generate a \f[CB]package\-info.class\f[R] file if
+This option does not generate a \f[CB]package\-info.class\f[R] file if
\f[CB]package\-info.java\f[R] contains only comments.
.RS
.PP
-\f[B]Note:\f[R]
-.PP
-A \f[CB]package\-info.class\f[R] file might be generated but be empty if
-all the annotations in the \f[CB]package\-info.java\f[R] file have
-\f[CB]RetentionPolicy.SOURCE\f[R].
+\f[B]Note:\f[R] A \f[CB]package\-info.class\f[R] file might be generated
+but be empty if all the annotations in the \f[CB]package\-info.java\f[R]
+file have \f[CB]RetentionPolicy.SOURCE\f[R].
.RE
.TP
.B \f[CB]nonempty\f[R]
@@ -903,6 +877,11 @@
.TP
.B \f[CB]\-Xplugin:\f[R]\f[I]name\f[R] \f[I]args\f[R]
Specifies the name and optional arguments for a plug\-in to be run.
+If \f[I]args\f[R] are provided, \f[I]name\f[R] and \f[I]args\f[R] should be
+quoted or otherwise escape the whitespace characters between the name
+and all the arguments.
+For details on the API for a plugin, see the API documentation for
+\f[B]jdk.compiler/com.sun.source.util.Plugin\f[R].
.RS
.RE
.TP
@@ -910,7 +889,7 @@
Specifies which file to read when both a source file and class file are
found for an implicitly compiled class using one of the following
options.
-See \f[B]Searching for Types\f[R].
+See \f[B]Searching for Module, Package and Type Declarations\f[R].
.RS
.IP \[bu] 2
\f[CB]\-Xprefer:newer\f[R]: Reads the newer of the source or class files
@@ -925,7 +904,7 @@
.B \f[CB]\-Xprint\f[R]
Prints a textual representation of specified types for debugging
purposes.
-This doesn\[aq]t perform annotation processing or compilation.
+This does not perform annotation processing or compilation.
The format of the output could change.
.RS
.RE
@@ -947,10 +926,56 @@
By default, compiler messages go to \f[CB]System.err\f[R].
.RS
.RE
-.SH JAVAC COMMAND\-LINE ARGUMENT FILES
+.SH ENVIRONMENT VARIABLES
+.SS CLASSPATH
+.PP
+If the \f[CB]\-\-class\-path\f[R] option or any of its alternate forms are
+not specified, the class path will default to the value of the
+\f[CB]CLASSPATH\f[R] environment variable if it is set.
+However, it is recommended that this environment variable should
+\f[I]not\f[R] be set, and that the \f[CB]\-\-class\-path\f[R] option should
+be used to provide an explicit value for the class path when one is
+required.
+.SS JDK_JAVAC_OPTIONS
+.PP
+The content of the \f[CB]JDK_JAVAC_OPTIONS\f[R] environment variable,
+separated by white\-spaces ( ) or white\-space characters (\f[CB]\\n\f[R],
+\f[CB]\\t\f[R], \f[CB]\\r\f[R], or \f[CB]\\f\f[R]) is prepended to the command
+line arguments passed to \f[CB]javac\f[R] as a list of arguments.
+.PP
+The encoding requirement for the environment variable is the same as the
+\f[CB]javac\f[R] command line on the system.
+\f[CB]JDK_JAVAC_OPTIONS\f[R] environment variable content is treated in
+the same manner as that specified in the command line.
.PP
-An argument file can include \f[CB]javac\f[R] options and source file
-names in any combination.
+Single quotes (\f[CB]\[aq]\f[R]) or double quotes (\f[CB]"\f[R]) can be used
+to enclose arguments that contain whitespace characters.
+All content between the open quote and the first matching close quote
+are preserved by simply removing the pair of quotes.
+In case a matching quote is not found, the launcher will abort with an
+error message.
+\f[CB]\@\f[R]\f[I]files\f[R] are supported as they are specified in the
+command line.
+However, as in \f[CB]\@\f[R]\f[I]files\f[R], use of a wildcard is not
+supported.
+.PP
+\f[B]Examples of quoting arguments containing white spaces:\f[R]
+.RS
+.PP
+\f[CB]export\ JDK_JAVAC_OPTIONS=\[aq]\@"C:\\white\ spaces\\argfile"\[aq]\f[R]
+.RE
+.RS
+.PP
+\f[CB]export\ JDK_JAVAC_OPTIONS=\[aq]"\@C:\\white\ spaces\\argfile"\[aq]\f[R]
+.RE
+.RS
+.PP
+\f[CB]export\ JDK_JAVAC_OPTIONS=\[aq]\@C:\\"white\ spaces"\\argfile\[aq]\f[R]
+.RE
+.SH COMMAND\-LINE ARGUMENT FILES
+.PP
+An argument file can include command\-line options and source file names
+in any combination.
The arguments within a file can be separated by spaces or new line
characters.
If a file name contains embedded spaces, then put the whole file name in
@@ -958,19 +983,19 @@
.PP
File names within an argument file are relative to the current
directory, not to the location of the argument file.
-Wildcards (*) aren\[aq]t allowed in these lists (such as for specifying
-\f[CB]*.java\f[R]).
-Use of the at sign (\f[CB]\@\f[R]) to recursively interpret files
-isn\[aq]t supported.
-The \f[CB]\-J\f[R] options aren\[aq]t supported because they\[aq]re passed
-to the launcher, which doesn\[aq]t support argument files.
+Wildcards (\f[CB]*\f[R]) are not allowed in these lists (such as for
+specifying \f[CB]*.java\f[R]).
+Use of the at sign (\f[CB]\@\f[R]) to recursively interpret files is not
+supported.
+The \f[CB]\-J\f[R] options are not supported because they\[aq]re passed to
+the launcher, which does not support argument files.
.PP
When executing the \f[CB]javac\f[R] command, pass in the path and name of
each argument file with the at sign (\f[CB]\@\f[R]) leading character.
When the \f[CB]javac\f[R] command encounters an argument beginning with
the at sign (\f[CB]\@\f[R]), it expands the contents of that file into the
argument list.
-.SH EXAMPLES OF USING JAVAC \@FILENAME
+.SS Examples of Using javac \@filename
.TP
.B Single Argument File
You could use a single argument file named \f[CB]argfile\f[R] to hold all
@@ -993,7 +1018,7 @@
.PP
Create a file named \f[CB]options\f[R] that contains the following:
.PP
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
.IP
.nf
\f[CB]
@@ -1040,6 +1065,845 @@
\f[CB]javac\ \@path1/options\ \@path2/classes\f[R]
.RE
.RE
+.SH ARRANGEMENT OF SOURCE CODE
+.PP
+In the Java language, classes and interfaces can be organized into
+packages, and packages can be organized into modules.
+\f[CB]javac\f[R] expects that the physical arrangement of source files in
+directories of the file system will mirror the organization of classes
+into packages, and packages into modules.
+.PP
+It is a widely adopted convention that module names and package names
+begin with a lower\-case letter, and that class names begin with an
+upper\-case letter.
+.SS Arrangement of Source Code for a Package
+.PP
+When classes and interfaces are organized into a package, the package is
+represented as a directory, and any subpackages are represented as
+subdirectories.
+.PP
+For example:
+.IP \[bu] 2
+The package \f[CB]p\f[R] is represented as a directory called \f[CB]p\f[R].
+.IP \[bu] 2
+The package \f[CB]p.q\f[R] \-\- that is, the subpackage \f[CB]q\f[R] of
+package \f[CB]p\f[R] \-\- is represented as the subdirectory \f[CB]q\f[R] of
+directory \f[CB]p\f[R].
+The directory tree representing package \f[CB]p.q\f[R] is therefore
+\f[CB]p\\q\f[R] on Windows, and \f[CB]p/q\f[R] on other systems.
+.IP \[bu] 2
+The package \f[CB]p.q.r\f[R] is represented as the directory tree
+\f[CB]p\\q\\r\f[R] (on Windows) or \f[CB]p/q/r\f[R] (on other systems).
+.PP
+Within a directory or subdirectory, \f[CB]\&.java\f[R] files represent
+classes and interfaces in the corresponding package or subpackage.
+.PP
+For example:
+.IP \[bu] 2
+The class \f[CB]X\f[R] declared in package \f[CB]p\f[R] is represented by
+the file \f[CB]X.java\f[R] in the \f[CB]p\f[R] directory.
+.IP \[bu] 2
+The class \f[CB]Y\f[R] declared in package \f[CB]p.q\f[R] is represented by
+the file \f[CB]Y.java\f[R] in the \f[CB]q\f[R] subdirectory of directory
+\f[CB]p\f[R].
+.IP \[bu] 2
+The class \f[CB]Z\f[R] declared in package \f[CB]p.q.r\f[R] is represented
+by the file \f[CB]Z.java\f[R] in the \f[CB]r\f[R] subdirectory of
+\f[CB]p\\q\f[R] (on Windows) or \f[CB]p/q\f[R] (on other systems).
+.PP
+In some situations, it is convenient to split the code into separate
+directories, each structured as described above, and the aggregate list
+of directories specified to \f[CB]javac\f[R].
+.SS Arrangement of Source Code for a Module
+.PP
+In the Java language, a module is a set of packages designed for reuse.
+In addition to \f[CB]\&.java\f[R] files for classes and interfaces, each
+module has a source file called \f[CB]module\-info.java\f[R] which:
+.IP "1." 3
+declares the module\[aq]s name;
+.IP "2." 3
+lists the packages exported by the module (to allow reuse by other
+modules);
+.IP "3." 3
+lists other modules required by the module (to reuse their exported
+packages).
+.PP
+When packages are organized into a module, the module is represented by
+one or more directories representing the packages in the module, one of
+which contains the \f[CB]module\-info.java\f[R] file.
+It may be convenient, but it is not required, to use a single directory,
+named after the module, to contain the \f[CB]module\-info.java\f[R] file
+alongside the directory tree which represents the packages in the module
+(i.e., the \f[I]package hierarchy\f[R] described above).
+The exact arrangement of source code for a module is typically dictated
+by the conventions adopted by a development environment (IDE) or build
+system.
+.PP
+For example:
+.IP \[bu] 2
+The module \f[CB]a.b.c\f[R] may be represented by the directory
+\f[CB]a.b.c\f[R], on all systems.
+.IP \[bu] 2
+The module\[aq]s declaration is represented by the file
+\f[CB]module\-info.java\f[R] in the \f[CB]a.b.c\f[R] directory.
+.IP \[bu] 2
+If the module contains package \f[CB]p.q.r\f[R], then the \f[CB]a.b.c\f[R]
+directory contains the directory tree \f[CB]p\\q\\r\f[R] (on Windows) or
+\f[CB]p/q/r\f[R] (on other systems).
+.PP
+The development environment may prescribe some directory hierarchy
+between the directory named for the module and the source files to be
+read by \f[CB]javac\f[R].
+.PP
+For example:
+.IP \[bu] 2
+The module \f[CB]a.b.c\f[R] may be represented by the directory
+\f[CB]a.b.c\f[R]
+.IP \[bu] 2
+The module\[aq]s declaration and the module\[aq]s packages may be in
+some subdirectory of \f[CB]a.b.c\f[R], such as \f[CB]src\\main\\java\f[R]
+(on Windows) or \f[CB]src/main/java\f[R] (on other systems).
+.SH CONFIGURING A COMPILATION
+.PP
+This section describes how to configure \f[CB]javac\f[R] to perform a
+basic compilation.
+.PP
+See \f[B]Configuring the Module System\f[R] for additional details for
+use when compiling for a release of the platform that supports modules.
+.SS Source Files
+.IP \[bu] 2
+Specify the source files to be compiled on the command line.
+.PP
+If there are no compilation errors, the corresponding class files will
+be placed in the \f[B]output directory\f[R].
+.PP
+Some systems may limit the amount you can put on a command line; to work
+around those limits, you can use \f[B]argument files\f[R].
+.PP
+When compiling code for modules, you can also specify source files
+indirectly, by using the \f[CB]\-\-module\f[R] or \f[CB]\-m\f[R] option; see
+\f[B]Standard Options\f[R].
+.SS Output Directory
+.IP \[bu] 2
+Use the \f[CB]\-d\f[R] option to specify an output directory in which to
+put the compiled class files.
+.PP
+This will normally be organized in a \f[B]package hierarchy\f[R], unless
+you are compiling source code from multiple modules, in which case it
+will be organized as a \f[B]module hierarchy\f[R].
+.PP
+When the compilation has been completed, if you are compiling one or
+more modules, you can place the output directory on the module path for
+the Java \f[B]launcher\f[R]; otherwise, you can place the place the
+output directory on the class path for the Java launcher.
+.SS Precompiled Code
+.PP
+The code to be compiled may refer to libraries beyond what is provided
+by the platform.
+If so, you must place these libraries on the class path or module path.
+If the library code is not in a module, place it on the class path; if
+it is in a module, place it on the module path.
+.IP \[bu] 2
+Use the \f[CB]\-\-class\-path\f[R] option to specify libraries to be
+placed on the class path.
+Locations on the class path should be organized in a \f[B]package
+hierarchy\f[R].
+You can also use alternate forms of the option: \f[CB]\-classpath\f[R] or
+\f[CB]\-cp\f[R].
+.IP \[bu] 2
+Use the \f[CB]\-\-module\-path\f[R] option to specify libraries to be
+placed on the module path.
+Locations on the module path should either be modules or directories of
+modules.
+You can also use an alternate form of the option: \f[CB]\-p\f[R].
+.RS 2
+.PP
+See \f[B]Configuring the Module System\f[R] for details on how to modify
+the default configuration of library modules.
+.RE
+.PP
+\f[B]Note\f[R]: the options for the class path and module path are not
+mutually exclusive, although it is not common to specify the class path
+when compiling code for one or more modules.
+.SS Additional Source Files
+.PP
+The code to be compiled may refer to types in additional source files
+that are not specified on the command line.
+If so, you must put those source files on either the source path or
+module path.
+You can only specify one of these options: if you are not compiling code
+for a module, or if you are only compiling code for a single module, use
+the source path; if you are compiling code for multiple modules, use the
+module source path.
+.IP \[bu] 2
+Use the \f[CB]\-\-source\-path\f[R] option to specify the locations of
+additional source files that may be read by javac.
+Locations on the source path should be organized in a \f[B]package
+hierarchy\f[R].
+You can also use an alternate form of the option: \f[CB]\-sourcepath\f[R].
+.IP \[bu] 2
+Use the \f[CB]\-\-module\-source\-path\f[R] option one or more times to
+specify the location of additional source files in different modules
+that may be read by javac, or when compiling source files in multiple
+modules.
+You can either specify the locations for each module
+\f[B]individually\f[R], or you can organize the source files so that you
+can specify the locations all \f[B]together\f[R].
+For more details, see \f[B]The Module Source Path Option\f[R].
+.PP
+If you want to be able to refer to types in additional source files but
+do not want them to be compiled, use the \f[CB]\-implicit\f[R] option.
+.PP
+\f[B]Note\f[R]: if you are compiling code for multiple modules, you must
+always specify a module source path, and all source files specified on
+the command line must be in one of the directories on the module source
+path, or in a subdirectory thereof.
+.SS Example of Compiling Multiple Source Files
+.PP
+This example compiles the \f[CB]Aloha.java\f[R], \f[CB]GutenTag.java\f[R],
+\f[CB]Hello.java\f[R], and \f[CB]Hi.java\f[R] source files in the
+\f[CB]greetings\f[R] package.
+.PP
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
+.IP
+.nf
+\f[CB]
+%\ javac\ greetings/*.java
+%\ ls\ greetings
+Aloha.class\ \ \ \ \ \ \ \ \ GutenTag.class\ \ \ \ \ \ Hello.class\ \ \ \ \ \ \ \ \ Hi.class
+Aloha.java\ \ \ \ \ \ \ \ \ \ GutenTag.java\ \ \ \ \ \ \ Hello.java\ \ \ \ \ \ \ \ \ \ Hi.java
+\f[R]
+.fi
+.PP
+\f[B]Windows:\f[R]
+.IP
+.nf
+\f[CB]
+C:\\>javac\ greetings\\*.java
+C:\\>dir\ greetings
+Aloha.class\ \ \ \ \ \ \ \ \ GutenTag.class\ \ \ \ \ \ Hello.class\ \ \ \ \ \ \ \ \ Hi.class
+Aloha.java\ \ \ \ \ \ \ \ \ \ GutenTag.java\ \ \ \ \ \ \ Hello.java\ \ \ \ \ \ \ \ \ \ Hi.java
+\f[R]
+.fi
+.SS Example of Specifying a User Class Path
+.PP
+After changing one of the source files in the previous example,
+recompile it:
+.PP
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
+.IP
+.nf
+\f[CB]
+pwd
+/examples
+javac\ greetings/Hi.java
+\f[R]
+.fi
+.PP
+\f[B]Windows:\f[R]
+.IP
+.nf
+\f[CB]
+C:\\>cd
+\\examples
+C:\\>javac\ greetings\\Hi.java
+\f[R]
+.fi
+.PP
+Because \f[CB]greetings.Hi\f[R] refers to other classes in the
+\f[CB]greetings\f[R] package, the compiler needs to find these other
+classes.
+The previous example works because the default user class path is the
+directory that contains the package directory.
+If you want to recompile this file without concern for which directory
+you are in, then add the examples directory to the user class path by
+setting \f[CB]CLASSPATH\f[R].
+This example uses the \f[CB]\-classpath\f[R] option.
+.PP
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
+.RS
+.PP
+\f[CB]javac\ \-classpath\ /examples\ /examples/greetings/Hi.java\f[R]
+.RE
+.PP
+\f[B]Windows:\f[R]
+.RS
+.PP
+\f[CB]C:\\>javac\ \-classpath\ \\examples\ \\examples\\greetings\\Hi.java\f[R]
+.RE
+.PP
+If you change \f[CB]greetings.Hi\f[R] to use a banner utility, then that
+utility also needs to be accessible through the user class path.
+.PP
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
+.IP
+.nf
+\f[CB]
+javac\ \-classpath\ /examples:/lib/Banners.jar\ \\
+\ \ \ \ \ \ \ \ \ \ \ \ /examples/greetings/Hi.java
+\f[R]
+.fi
+.PP
+\f[B]Windows:\f[R]
+.IP
+.nf
+\f[CB]
+C:\\>javac\ \-classpath\ \\examples;\\lib\\Banners.jar\ ^
+\ \ \ \ \ \ \ \ \ \ \ \ \\examples\\greetings\\Hi.java
+\f[R]
+.fi
+.PP
+To execute a class in the \f[CB]greetings\f[R] package, the program needs
+access to the \f[CB]greetings\f[R] package, and to the classes that the
+\f[CB]greetings\f[R] classes use.
+.PP
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
+.RS
+.PP
+\f[CB]java\ \-classpath\ /examples:/lib/Banners.jar\ greetings.Hi\f[R]
+.RE
+.PP
+\f[B]Windows:\f[R]
+.RS
+.PP
+\f[CB]C:\\>java\ \-classpath\ \\examples;\\lib\\Banners.jar\ greetings.Hi\f[R]
+.RE
+.SH CONFIGURING THE MODULE SYSTEM
+.PP
+If you want to include additional modules in your compilation, use the
+\f[CB]\-\-add\-modules\f[R] option.
+This may be necessary when you are compiling code that is not in a
+module, or which is in an automatic module, and the code refers to API
+in the additional modules.
+.PP
+If you want to restrict the set of modules in your compilation, use the
+\f[CB]\-\-limit\-modules\f[R] option.
+This may be useful if you want to ensure that the code you are compiling
+is capable of running on a system with a limited set of modules
+installed.
+.PP
+If you want to break encapsulation and specify that additional packages
+should be considered as exported from a module, use the
+\f[CB]\-\-add\-exports\f[R] option.
+This may be useful when performing white\-box testing; relying on access
+to internal API in production code is strongly discouraged.
+.PP
+If you want to specify that additional packages should be considered as
+required by a module, use the \f[CB]\-\-add\-reads\f[R] option.
+This may be useful when performing white\-box testing; relying on access
+to internal API in production code is strongly discouraged.
+.PP
+You can patch additional content into any module using the
+\f[CB]\-\-patch\-module\f[R] option.
+See [Patching a Module] for more details.
+.SH SEARCHING FOR MODULE, PACKAGE AND TYPE DECLARATIONS
+.PP
+To compile a source file, the compiler often needs information about a
+module or type, but the declaration is not in the source files specified
+on the command line.
+.PP
+\f[CB]javac\f[R] needs type information for every class or interface used,
+extended, or implemented in the source file.
+This includes classes and interfaces not explicitly mentioned in the
+source file, but that provide information through inheritance.
+.PP
+For example, when you create a subclass of \f[CB]java.awt.Window\f[R], you
+are also using the ancestor classes of \f[CB]Window\f[R]:
+\f[CB]java.awt.Container\f[R], \f[CB]java.awt.Component\f[R], and
+\f[CB]java.lang.Object\f[R].
+.PP
+When compiling code for a module, the compiler also needs to have
+available the declaration of that module.
+.PP
+A successful search may produce a class file, a source file, or both.
+If both are found, then you can use the \f[CB]\-Xprefer\f[R] option to
+instruct the compiler which to use; see \f[B]Extra Options\f[R].
+.PP
+If a search finds and uses a source file, then by default \f[CB]javac\f[R]
+compiles that source file.
+This behavior can be altered with \f[CB]\-implicit\f[R]; see \f[B]Standard
+Options\f[R].
+.PP
+The compiler might not discover the need for some type information until
+after annotation processing completes.
+When the type information is found in a source file and no
+\f[CB]\-implicit\f[R] option is specified, the compiler gives a warning
+that the file is being compiled without being subject to annotation
+processing.
+To disable the warning, either specify the file on the command line (so
+that it will be subject to annotation processing) or use the
+\f[CB]\-implicit\f[R] option to specify whether or not class files should
+be generated for such source files.
+.PP
+The way that \f[CB]javac\f[R] locates the declarations of those types
+depends on whether the reference exists within code for a module or not.
+.SS Searching Package Oriented Paths
+.PP
+When searching for a source or class file on a path composed of package
+oriented locations, \f[CB]javac\f[R] will check each location on the path
+in turn for the possible presence of the file.
+The first occurrence of a particular file shadows (hides) any subsequent
+occurrences of like\-named files.
+This shadowing does not affect any search for any files with a different
+name.
+This can be convenient when searching for source files, which may be
+grouped in different locations, such as shared code, platform\-specific
+code and generated code.
+It can also be useful when injecting alternate versions of a class file
+into a package, to debugging or other instrumentation reasons.
+But, it can also be dangerous, such as when putting incompatible
+different versions of a library on the class path.
+.SS Searching Module Oriented Paths
+.PP
+Prior to scanning any module paths for any package or type declarations,
+\f[CB]javac\f[R] will lazily scan the following paths and locations to
+determine the modules that will be used in the compilation.
+.IP \[bu] 2
+The module source path (see the \f[CB]\-\-module\-source\-path\f[R]
+option)
+.IP \[bu] 2
+The path for upgradeable modules (see the
+\f[CB]\-\-upgrade\-module\-path\f[R] option)
+.IP \[bu] 2
+The system modules (see the \f[CB]\-\-system\f[R] option)
+.IP \[bu] 2
+The user module path ( see the \f[CB]\-\-module\-path\f[R] option)
+.PP
+For any module, the first occurrence of the module during the scan
+completely shadows (hides) any subsequent appearance of a like\-named
+module.
+While locating the modules, \f[CB]javac\f[R] is able to determine the
+packages exported by the module and to associate with each module a
+package oriented path for the contents of the module.
+For any previously compiled module, this path will typically be a single
+entry for either a directory or a file that provides an internal
+directory\-like hierarchy, such as a JAR file.
+Thus, when searching for a type that is in a package that is known to be
+exported by a module, \f[CB]javac\f[R] can locate the declaration directly
+and efficiently.
+.SS Searching for the Declaration of a Module
+.PP
+If the module has been previously compiled, the module declaration is
+located in a file named \f[CB]module\-info.class\f[R] in the root of the
+package hierarchy for the content of the module.
+.PP
+If the module is one of those currently being compiled, the module
+declaration will be either the file named \f[CB]module\-info.class\f[R] in
+the root of the package hierarchy for the module in the class output
+directory, or the file named \f[CB]module\-info.java\f[R] in one of the
+locations on the source path or one the module source path for the
+module.
+.SS Searching for the Declaration of a Type When the Reference is not in
+a Module
+.PP
+When searching for a type that is referenced in code that is not in a
+module, \f[CB]javac\f[R] will look in the following places:
+.IP \[bu] 2
+The platform classes (or the types in exported packages of the platform
+modules) (This is for compiled class files only.)
+.IP \[bu] 2
+Types in exported packages of any modules on the module path, if
+applicable.
+(This is for compiled class files only.)
+.IP \[bu] 2
+Types in packages on the class path and/or source path:
+.RS 2
+.IP \[bu] 2
+If both are specified, \f[CB]javac\f[R] looks for compiled class files on
+the class path and for source files on the source path.
+.IP \[bu] 2
+If the class path is specified, but not source path, \f[CB]javac\f[R]
+looks for both compiled class files and source files on the class path.
+.IP \[bu] 2
+If the class path is not specified, it defaults to the current
+directory.
+.RE
+.PP
+When looking for a type on the class path and/or source path, if both a
+compiled class file and a source file are found, the most recently
+modified file will be used by default.
+If the source file is newer, it will be compiled and will may override
+any previously compiled version of the file.
+You can use the \f[CB]\-Xprefer\f[R] option to override the default
+behavior.
+.SS Searching for the Declaration of a Type When the Reference is in a
+Module
+.PP
+When searching for a type that is referenced in code in a module,
+\f[CB]javac\f[R] will examine the declaration of the enclosing module to
+determine if the type is in a package that is exported from another
+module that is readable by the enclosing module.
+If so, \f[CB]javac\f[R] will simply and directly go to the definition of
+that module to find the definition of the required type.
+Unless the module is another of the modules being compiled,
+\f[CB]javac\f[R] will only look for compiled class files files.
+In other words, \f[CB]javac\f[R] will not look for source files in
+platform modules or modules on the module path.
+.PP
+If the type being referenced is not in some other readable module,
+\f[CB]javac\f[R] will examine the module being compiled to try and find
+the declaration of the type.
+\f[CB]javac\f[R] will look for the declaration of the type as follows:
+.IP \[bu] 2
+Source files specified on the command line or on the source path or
+module source path.
+.IP \[bu] 2
+Previously compiled files in the output directory.
+.SH DIRECTORY HIERARCHIES
+.PP
+\f[CB]javac\f[R] generally assumes that source files and compiled class
+files will be organized in a file system directory hierarchy or in a
+type of file that supports in an internal directory hierarchy, such as a
+JAR file.
+Three different kinds of hierarchy are supported: a \f[I]package
+hierarchy\f[R], a \f[I]module hierarchy\f[R], and a \f[I]module source
+hierarchy\f[R].
+.PP
+While \f[CB]javac\f[R] is fairly relaxed about the organization of source
+code, beyond the expectation that source will be organized in one or
+package hierarchies, and can generally accomodate organizations
+prescribed by development environments and build tools, Java tools in
+general, and \f[CB]javac\f[R] and the Java launcher in particular, are
+more stringent regarding the organization of compiled class files, and
+will be organized in package hierarchies or module hierarchies, as
+appropriate.
+.PP
+The location of these hierarchies are specified to \f[CB]javac\f[R] with
+command\-line options, whose names typically end in "path", like
+\f[CB]\-\-source\-path\f[R] or \f[CB]\-\-class\-path\f[R].
+Also as a general rule, path options whose name includes the word
+\f[CB]module\f[R], like \f[CB]\-\-module\-path\f[R], are used to specify
+module hierarchies, although some module\-related path options allow a
+package hierarchy to be specified on a per\-module basis.
+All other path options are used to specify package hierarchies.
+.SS Package Hierarchy
+.PP
+In a package hierarchy, directories and subdirectories are used to
+represent the component parts of the package name, with the source file
+or compiled class file for a type being stored as a file with an
+extension of \f[CB]\&.java\f[R] or \f[CB]\&.class\f[R] in the most nested
+directory.
+.PP
+For example, in a package hierarchy, the source file for a class
+\f[CB]com.example.MyClass\f[R] will be stored in the file
+\f[I]com/example/MyClass.java\f[R]
+.SS Module Hierarchy
+.PP
+In a module hierarchy, the first level of directories are named for the
+modules in the hierarchy; within each of those directories the contents
+of the module are organized in package hierarchies.
+.PP
+For example, in a module hierarchy, the compiled class file for a type
+called \f[CB]com.example.MyClass\f[R] in a module called
+\f[CB]my.library\f[R] will be stored in
+\f[I]my.library/com/example/MyClass.class\f[R].
+.PP
+The various output directories used by \f[CB]javac\f[R] (the class output
+directory, the source output directory, and native header output
+directory) will all be organized in a module hierarchy when multiple
+modules are being compiled.
+.SS Module Source Hierarchy
+.PP
+Although the source for each individual module should always be
+organized in a package hierarchy, it may be convenient to group those
+hierarchies into a module source hierarchy.
+This is similar to a module hierarchy, except that there may be
+intervening directories between the directory for the module and the
+directory that is the root of the package hierarchy for the source code
+of the module.
+.PP
+For example, in a module source hierarchy, the source file for a type
+called \f[CB]com.example.MyClass\f[R] in a module called
+\f[CB]my.library\f[R] may be stored in a file such as
+\f[I]my.library/src/main/java/com/example/MyClass.java\f[R].
+.SH THE MODULE SOURCE PATH OPTION
+.PP
+The \f[CB]\-\-module\-source\-path\f[R] option has two forms: a
+\f[I]module\-specific form\f[R], in which a package path is given for
+each module containing code to be compiled, and a
+\f[I]module\-pattern\f[R] form, in which the source path for each module
+is specified by a pattern.
+The module\-specific form is generally simpler to use when only a small
+number of modules are involved; the module\-pattern form may be more
+convenient when the number of modules is large and the modules are
+organized in a regular manner that can be described by a pattern.
+.PP
+Multiple instances of the \f[CB]\-\-module\-source\-path\f[R] option may
+be given, each one using either the module\-pattern form or the
+module\-specific form, subject to the following limitations:
+.IP \[bu] 2
+the module\-pattern form may be used at most once
+.IP \[bu] 2
+the module\-specific form may be used at most once for any given module
+.PP
+If the module\-specific form is used for any module, the associated
+search path overrides any path that might otherwise have been inferred
+from the module\-pattern form.
+.SS Module\-specific form
+.PP
+The module\-specific form allows an explicit search path to be given for
+any specific module.
+This form is:
+.IP \[bu] 2
+\f[CB]\-\-module\-source\-path\f[R]
+\f[I]module\-name\f[R]\f[CB]=\f[R]\f[I]file\-path\f[R]
+(\f[I]path\-separator\f[R] \f[I]file\-path\f[R])*
+.PP
+The path separator character is \f[CB];\f[R] on Windows, and \f[CB]:\f[R]
+otherwise.
+.PP
+\f[B]Note:\f[R] this is similar to the form used for the
+\f[CB]\-\-patch\-module\f[R] option.
+.SS Module\-pattern form
+.PP
+The module\-pattern form allows a concise specification of the module
+source path for any number of modules organized in regular manner.
+.IP \[bu] 2
+\f[CB]\-\-module\-source\-path\f[R] \f[I]pattern\f[R]
+.PP
+The pattern is defined by the following rules, which are applied in
+order:
+.IP \[bu] 2
+The argument is considered to be a series of segments separated by the
+path separator character (\f[CB];\f[R] on Windows, and \f[CB]:\f[R]
+otherwise).
+.IP \[bu] 2
+Each segment containing curly braces of the form
+.RS 2
+.IP
+.nf
+\f[CB]
+string1{alt1\ (\ ,alt2\ )*\ }\ string2
+\f[R]
+.fi
+.PP
+is considered to be replaced by a series of segments formed by
+"expanding" the braces:
+.IP
+.nf
+\f[CB]
+string1\ alt1\ string2
+string1\ alt2\ string2
+and\ so\ on...
+\f[R]
+.fi
+.PP
+The braces may be nested.
+.PP
+This rule is applied for all such usages of braces.
+.RE
+.IP \[bu] 2
+Each segment must have at most one asterisk (\f[CB]*\f[R]).
+If a segment does not contain an asterisk, it is considered to be as
+though the file separator character and an asterisk are appended.
+.RS 2
+.PP
+For any module \f[I]M\f[R], the source path for that module is formed
+from the series of segments obtained by substituting the module name
+\f[I]M\f[R] for the asterisk in each segment.
+.PP
+\f[B]Note\f[R]: in this context, the asterisk is just used as a special
+marker, to denote the position in the path of the module name.
+It should not be confused with the use of \f[CB]*\f[R] as a file name
+wildcard character, as found on most operating systems.
+.RE
+.SH PATCHING MODULES
+.PP
+javac allows any content, whether in source or compiled form, to be
+patched into any module using the \f[CB]\-\-patch\-module\f[R] option.
+You may want to do this to compile alternative implementations of a
+class to be patched at runtime into a JVM, or to inject additional
+classes into the module, such as when testing.
+.PP
+The form of the option is:
+.IP \[bu] 2
+\f[CB]\-\-patch\-module\f[R]
+\f[I]module\-name\f[R]\f[CB]=\f[R]\f[I]file\-path\f[R]
+(\f[I]path\-separator\f[R] \f[I]file\-path\f[R] )*
+.PP
+The path separator character is \f[CB];\f[R] on Windows, and \f[CB]:\f[R]
+otherwise.
+The paths given for the module must specify the root of a package
+hierarchy for the contents of the module
+.PP
+The option may be given at most once for any given module.
+Any content on the path will hide any like\-named content later in the
+path and in the patched module.
+.PP
+When patching source code into more than one module, the
+\f[CB]\-\-module\-source\-path\f[R] must also be used, so that the output
+directory is organized in a module hierarchy, and capable of holding the
+compiled class files for the modules being compiled.
+.SH ANNOTATION PROCESSING
+.PP
+The \f[CB]javac\f[R] command provides direct support for annotation
+processing.
+.PP
+The API for annotation processors is defined in the
+\f[CB]javax.annotation.processing\f[R] and \f[CB]javax.lang.model\f[R]
+packages and subpackages.
+.SS How Annotation Processing Works
+.PP
+Unless annotation processing is disabled with the \f[CB]\-proc:none\f[R]
+option, the compiler searches for any annotation processors that are
+available.
+The search path can be specified with the \f[CB]\-processorpath\f[R]
+option.
+If no path is specified, then the user class path is used.
+Processors are located by means of service provider\-configuration files
+named \f[CB]META\-INF/services/javax.annotation.processing\f[R].
+Processor on the search path.
+Such files should contain the names of any annotation processors to be
+used, listed one per line.
+Alternatively, processors can be specified explicitly, using the
+\f[CB]\-processor\f[R] option.
+.PP
+After scanning the source files and classes on the command line to
+determine what annotations are present, the compiler queries the
+processors to determine what annotations they process.
+When a match is found, the processor is called.
+A processor can claim the annotations it processes, in which case no
+further attempt is made to find any processors for those annotations.
+After all of the annotations are claimed, the compiler does not search
+for additional processors.
+.PP
+If any processors generate new source files, then another round of
+annotation processing occurs: Any newly generated source files are
+scanned, and the annotations processed as before.
+Any processors called on previous rounds are also called on all
+subsequent rounds.
+This continues until no new source files are generated.
+.PP
+After a round occurs where no new source files are generated, the
+annotation processors are called one last time, to give them a chance to
+complete any remaining work.
+Finally, unless the \f[CB]\-proc:only\f[R] option is used, the compiler
+compiles the original and all generated source files.
+.PP
+If you use an annotation processor that generates additional source
+files to be included in the compilation, you can specify a default
+module to be used for the newly generated files, for use when a module
+declaration is not also generated.
+In this case, use the \f[CB]\-\-default\-module\-for\-created\-files\f[R]
+option.
+.SS Compilation Environment and Runtime Environment.
+.PP
+The declarations in source files and previously compiled class files are
+analyzed by \f[CB]javac\f[R] in a \f[I]compilation environment\f[R] that is
+distinct from the \f[I]runtime environment\f[R] used to execute
+\f[CB]javac\f[R] itself.
+Although there is a deliberate similarity between many \f[CB]javac\f[R]
+options and like\-named options for the Java \f[B]launcher\f[R], such as
+\f[CB]\-\-class\-path\f[R], \f[CB]\-\-module\-path\f[R] and so on, it is
+important to understand that in general the \f[CB]javac\f[R] options just
+affect the environment in which the source files are compiled, and do
+not affect the operation of \f[CB]javac\f[R] itself.
+.PP
+The distinction between the compilation environment and runtime
+environment is significant when it comes to using annotation processors.
+Although annotations processors process elements (declarations) that
+exist in the compilation environment, the annotation processor itself is
+executed in the runtime environment.
+If an annotation processor has dependencies on libraries that are not in
+modules, the libraries can be placed, along with the annotation
+processor itself, on the processor path.
+(See the \f[CB]\-\-processor\-path\f[R] option.) If the annotation
+processor and its dependencies are in modules, you should use the
+processor module path instead.
+(See the \f[CB]\-\-processor\-module\-path\f[R] option.) When those are
+insufficient, it may be necessary to provide further configuration of
+the runtime environment.
+This can be done in two ways:
+.IP "1." 3
+If \f[CB]javac\f[R] is invoked from the command line, options can be
+passed to the underlying runtime by prefixing the option with
+\f[CB]\-J\f[R].
+(See the \f[CB]\-J\f[R] option.)
+.IP "2." 3
+You can start an instance of a Java Virtual Machine directly and use
+command line options and API to configure an environment in which
+\f[CB]javac\f[R] can be invoked via one of its \f[B]APIs\f[R].
+.SH COMPILING FOR EARLIER RELEASES OF THE PLATFORM
+.PP
+\f[CB]javac\f[R] can compile code that is to be used on other releases of
+the platform, using either the \f[CB]\-\-release\f[R] option, or the
+\f[CB]\-\-source\f[R]/\f[CB]\-source\f[R] and
+\f[CB]\-\-target\f[R]/\f[CB]\-target\f[R] options, together with additional
+options to specify the platform classes.
+.PP
+Depending on the desired platform release, there are some restrictions
+on some of the options that can be used.
+.IP \[bu] 2
+When compiling for JDK 8 and earlier releases, you cannot use any option
+that is intended for use with the module system.
+This includes all of the following options:
+.RS 2
+.IP \[bu] 2
+\f[CB]\-\-module\-source\-path\f[R], \f[CB]\-\-upgrade\-module\-path\f[R],
+\f[CB]\-\-system\f[R], \f[CB]\-\-module\-path\f[R],
+\f[CB]\-\-add\-modules\f[R], \f[CB]\-\-add\-exports\f[R],
+\f[CB]\-\-add\-opens\f[R], \f[CB]\-\-add\-reads\f[R],
+\f[CB]\-\-limit\-modules\f[R], \f[CB]\-\-patch\-module\f[R]
+.PP
+If you use the \f[CB]\-\-source\f[R]/\f[CB]\-source\f[R] or
+\f[CB]\-\-target\f[R]/\f[CB]\-target\f[R] options, you should also set the
+appropriate platform classes using the boot class path family of
+options.
+.RE
+.IP \[bu] 2
+When compiling for JDK 9 and later releases, you cannot use any option
+that is intended to configure the boot class path.
+This includes all of the following options:
+.RS 2
+.IP \[bu] 2
+\f[CB]\-Xbootclasspath/p:\f[R], \f[CB]\-Xbootclasspath\f[R],
+\f[CB]\-Xbootclasspath/a:\f[R], \f[CB]\-endorseddirs\f[R],
+\f[CB]\-Djava.endorsed.dirs\f[R], \f[CB]\-extdirs\f[R],
+\f[CB]\-Djava.ext.dirs\f[R], \f[CB]\-profile\f[R]
+.PP
+If you use the \f[CB]\-\-source\f[R]/\f[CB]\-source\f[R] or
+\f[CB]\-\-target\f[R]/\f[CB]\-target\f[R] options, you should also set the
+appropriate platform classes using the \f[CB]\-\-system\f[R] option to
+give the location of an appropriate installed release of JDK.
+.RE
+.PP
+When using the \f[CB]\-\-release\f[R] option, only the supported
+documented API for that release may be used; you cannot use any options
+to break encapsulation to access any internal classes.
+.SH APIS
+.PP
+The \f[CB]javac\f[R] compiler can be invoked using an API in three
+different ways:
+.TP
+.B The \f[B]Java Compiler API\f[R]
+This provides the most flexible way to invoke the compiler, including
+the ability to compile source files provided in memory buffers or other
+non\-standard file systems.
+.RS
+.RE
+.TP
+.B The \f[B]ToolProvider API\f[R]
+A \f[CB]ToolProvider\f[R] for \f[CB]javac\f[R] can be obtained by calling
+\f[CB]ToolProvider.findFirst("javac")\f[R].
+This returns an object with the equivalent functionality of the
+command\-line tool.
+.RS
+.PP
+\f[B]Note\f[R]: This API should not be confused with the like\-named API
+in the \f[B]\f[BC]javax.tools\f[B]\f[R] package.
+.RE
+.TP
+.B The \f[CB]javac\f[R] \f[B]Legacy API\f[R]
+This API is retained for backward compatibility only.
+All new code should use either the Java Compiler API or the ToolProvider
+API.
+.RS
+.RE
+.PP
+\f[B]Note:\f[R] All other classes and methods found in a package with
+names that start with \f[CB]com.sun.tools.javac\f[R] (subpackages of
+\f[CB]com.sun.tools.javac\f[R]) are strictly internal and subject to
+change at any time.
.SH EXAMPLES OF USING \-XLINT KEYS
.TP
.B \f[CB]cast\f[R]
@@ -1074,8 +1938,8 @@
.TP
.B \f[CB]dep\-ann\f[R]
Warns about items that are documented with the \f[CB]\@deprecated\f[R]
-Javadoc comment, but don\[aq]t have the \f[CB]\@Deprecated\f[R]
-annotation, for example:
+Javadoc comment, but do not have the \f[CB]\@Deprecated\f[R] annotation,
+for example:
.RS
.IP
.nf
@@ -1117,10 +1981,11 @@
Checks the switch blocks for fall\-through cases and provides a warning
message for any that are found.
Fall\-through cases are cases in a switch block, other than the last
-case in the block, whose code doesn\[aq]t include a break statement,
-allowing code execution to fall through from that case to the next case.
+case in the block, whose code does not include a \f[CB]break\f[R]
+statement, allowing code execution to fall through from that case to the
+next case.
For example, the code following the case 1 label in this switch block
-doesn\[aq]t end with a break statement:
+does not end with a \f[CB]break\f[R] statement:
.RS
.IP
.nf
@@ -1141,8 +2006,8 @@
.RE
.TP
.B \f[CB]finally\f[R]
-Warns about \f[CB]finally\f[R] clauses that can\[aq]t be completed
-normally, for example:
+Warns about \f[CB]finally\f[R] clauses that cannot be completed normally,
+for example:
.RS
.IP
.nf
@@ -1172,7 +2037,7 @@
.TP
.B \f[CB]options\f[R]
Warns about issues that related to the use of command\-line options.
-See \f[B]Cross\-Compilation Options for javac\f[R].
+See \f[B]Compiling for Earlier Releases of the Platform\f[R].
.RS
.RE
.TP
@@ -1218,12 +2083,12 @@
Warns about invalid path elements and nonexistent path directories on
the command line (with regard to the class path, the source path, and
other paths).
-Such warnings can\[aq]t be suppressed with the
-\f[CB]\@SuppressWarnings\f[R] annotation.
+Such warnings cannot be suppressed with the \f[CB]\@SuppressWarnings\f[R]
+annotation.
For example:
.RS
.IP \[bu] 2
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
+\f[B]Oracle Solaris, Linux, and macOS:\f[R]
\f[CB]javac\ \-Xlint:path\ \-classpath\ /nonexistentpath\ Example.java\f[R]
.IP \[bu] 2
\f[B]Windows:\f[R]
@@ -1233,8 +2098,8 @@
.B \f[CB]processing\f[R]
Warns about issues related to annotation processing.
The compiler generates this warning when you have a class that has an
-annotation, and you use an annotation processor that can\[aq]t handle
-that type of exception.
+annotation, and you use an annotation processor that cannot handle that
+type of exception.
For example, the following is a simple annotation processor:
.RS
.PP
@@ -1306,7 +2171,7 @@
\f[CB]void\ countElements(List\ l)\ {\ ...\ }\f[R]
.RE
.PP
-The following example doesn\[aq]t generate a \f[CB]rawtypes\f[R] warning:
+The following example does not generate a \f[CB]rawtypes\f[R] warning:
.RS
.PP
\f[CB]void\ countElements(List<?>\ l)\ {\ ...\ }\f[R]
@@ -1354,7 +2219,7 @@
\f[R]
.fi
.PP
-If a serializable class doesn\[aq]t explicitly declare a field named
+If a serializable class does not explicitly declare a field named
\f[CB]serialVersionUID\f[R], then the serialization runtime environment
calculates a default \f[CB]serialVersionUID\f[R] value for that class
based on various aspects of the class, as described in the Java Object
@@ -1372,8 +2237,7 @@
.RE
.TP
.B \f[CB]static\f[R]
-Warns about issues relating to the use of statics variables, for
-example:
+Warns about issues relating to the use of static variables, for example:
.RS
.IP
.nf
@@ -1409,8 +2273,7 @@
Warns about issues relating to the use of \f[CB]try\f[R] blocks, including
try\-with\-resources statements.
For example, a warning is generated for the following statement because
-the resource \f[CB]ac\f[R] declared in the \f[CB]try\f[R] block isn\[aq]t
-used:
+the resource \f[CB]ac\f[R] declared in the \f[CB]try\f[R] block is not used:
.RS
.IP
.nf
@@ -1440,10 +2303,9 @@
\f[CB]List<String>\f[R].
When the \f[CB]List\f[R] referenced by \f[CB]l\f[R] is assigned to
\f[CB]ls\f[R], the compiler generates an unchecked warning.
-At compile time, the compiler and JVM can\[aq]t determine whether
+At compile time, the compiler and JVM cannot determine whether
\f[CB]l\f[R] refers to a \f[CB]List<String>\f[R] type.
-In this case, \f[CB]l\f[R] doesn\[aq]t refer to a \f[CB]List<String>\f[R]
-type.
+In this case, \f[CB]l\f[R] does not refer to a \f[CB]List<String>\f[R] type.
As a result, heap pollution occurs.
.PP
A heap pollution situation occurs when the \f[CB]List\f[R] object
@@ -1452,7 +2314,7 @@
type, \f[CB]List<String>\f[R].
However, the compiler still allows this assignment.
It must allow this assignment to preserve backward compatibility with
-releases of Java SE that don\[aq]t support generics.
+releases of Java SE that do not support generics.
Because of type erasure, \f[CB]List<Number>\f[R] and \f[CB]List<String>\f[R]
both become \f[CB]List\f[R].
Consequently, the compiler allows the assignment of the object
@@ -1477,7 +2339,7 @@
\f[R]
.fi
.PP
-A non\-reifiable type is a type whose type information isn\[aq]t fully
+A non\-reifiable type is a type whose type information is not fully
available at runtime.
.PP
The compiler generates the following warning for the definition of the
@@ -1491,8 +2353,8 @@
.PP
When the compiler encounters a varargs method, it translates the
\f[CB]varargs\f[R] formal parameter into an array.
-However, the Java programming language doesn\[aq]t permit the creation
-of arrays of parameterized types.
+However, the Java programming language does not permit the creation of
+arrays of parameterized types.
In the method \f[CB]ArrayBuilder.addToList\f[R], the compiler translates
the \f[CB]varargs\f[R] formal parameter \f[CB]T...\f[R] elements to the
formal parameter \f[CB]T[]\f[R] elements, an array.
@@ -1500,274 +2362,3 @@
\f[CB]varargs\f[R] formal parameter to \f[CB]Object[]\f[R] elements.
Consequently, there\[aq]s a possibility of heap pollution.
.RE
-.SH EXAMPLE OF COMPILING BY PROVIDING COMMAND\-LINE ARGUMENTS
-.PP
-To compile as though providing command\-line arguments, use the
-following syntax:
-.RS
-.PP
-\f[CB]JavaCompiler\ javac\ =\ ToolProvider.getSystemJavaCompiler();\f[R]
-.RE
-.PP
-The example writes diagnostics to the standard output stream and returns
-the exit code that \f[CB]javac\f[R] command would give when called from
-the command line.
-.PP
-You can use other methods in the \f[CB]javax.tools.JavaCompiler\f[R]
-interface to handle diagnostics, control where files are read from and
-written to, and more.
-.SH OLD INTERFACE
-.PP
-\f[B]Note:\f[R]
-.PP
-This API is retained for backward compatibility only.
-All new code should use the Java Compiler API.
-.PP
-The \f[CB]com.sun.tools.javac.Main\f[R] class provides two static methods
-to call the compiler from a program:
-.IP
-.nf
-\f[CB]
-public\ static\ int\ compile(String[]\ args);
-public\ static\ int\ compile(String[]\ args,\ PrintWriter\ out);
-\f[R]
-.fi
-.PP
-The \f[CB]args\f[R] parameter represents any of the command\-line
-arguments that would typically be passed to the compiler.
-.PP
-The \f[CB]out\f[R] parameter indicates where the compiler diagnostic
-output is directed.
-.PP
-The \f[CB]return\f[R] value is equivalent to the \f[CB]exit\f[R] value from
-\f[CB]javac\f[R].
-.PP
-\f[B]Note:\f[R]
-.PP
-All other classes and methods found in a package with names that start
-with \f[CB]com.sun.tools.javac\f[R] (subpackages of
-\f[CB]com.sun.tools.javac\f[R]) are strictly internal and subject to
-change at any time.
-.SH EXAMPLE OF COMPILING MULTIPLE SOURCE FILES
-.PP
-This example compiles the \f[CB]Aloha.java\f[R], \f[CB]GutenTag.java\f[R],
-\f[CB]Hello.java\f[R], and \f[CB]Hi.java\f[R] source files in the
-\f[CB]greetings\f[R] package.
-.PP
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
-.IP
-.nf
-\f[CB]
-%\ javac\ greetings/*.java
-%\ ls\ greetings
-Aloha.class\ \ \ \ \ \ \ \ \ GutenTag.class\ \ \ \ \ \ Hello.class\ \ \ \ \ \ \ \ \ Hi.class
-Aloha.java\ \ \ \ \ \ \ \ \ \ GutenTag.java\ \ \ \ \ \ \ Hello.java\ \ \ \ \ \ \ \ \ \ Hi.java
-\f[R]
-.fi
-.PP
-\f[B]Windows:\f[R]
-.IP
-.nf
-\f[CB]
-C:\\>javac\ greetings\\*.java
-C:\\>dir\ greetings
-Aloha.class\ \ \ \ \ \ \ \ \ GutenTag.class\ \ \ \ \ \ Hello.class\ \ \ \ \ \ \ \ \ Hi.class
-Aloha.java\ \ \ \ \ \ \ \ \ \ GutenTag.java\ \ \ \ \ \ \ Hello.java\ \ \ \ \ \ \ \ \ \ Hi.java
-\f[R]
-.fi
-.SH EXAMPLE OF SPECIFYING A USER CLASS PATH
-.PP
-After changing one of the source files in the previous example,
-recompile it:
-.PP
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
-.IP
-.nf
-\f[CB]
-pwd
-/examples
-javac\ greetings/Hi.java
-\f[R]
-.fi
-.PP
-\f[B]Windows:\f[R]
-.IP
-.nf
-\f[CB]
-C:\\>cd
-\\examples
-C:\\>javac\ greetings\\Hi.java
-\f[R]
-.fi
-.PP
-Because \f[CB]greetings.Hi\f[R] refers to other classes in the
-\f[CB]greetings\f[R] package, the compiler needs to find these other
-classes.
-The previous example works because the default user class path is the
-directory that contains the package directory.
-If you want to recompile this file without concern for which directory
-you are in, then add the examples directory to the user class path by
-setting \f[CB]CLASSPATH\f[R].
-This example uses the \f[CB]\-classpath\f[R] option.
-.PP
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
-.RS
-.PP
-\f[CB]javac\ \-classpath\ /examples\ /examples/greetings/Hi.java\f[R]
-.RE
-.PP
-\f[B]Windows:\f[R]
-.RS
-.PP
-\f[CB]C:\\>javac\ \-classpath\ \\examples\ \\examples\\greetings\\Hi.java\f[R]
-.RE
-.PP
-If you change \f[CB]greetings.Hi\f[R] to use a banner utility, then that
-utility also needs to be accessible through the user class path.
-.PP
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
-.IP
-.nf
-\f[CB]
-javac\ \-classpath\ /examples:/lib/Banners.jar\ \\
-\ \ \ \ \ \ \ \ \ \ \ \ /examples/greetings/Hi.java
-\f[R]
-.fi
-.PP
-\f[B]Windows:\f[R]
-.IP
-.nf
-\f[CB]
-C:\\>javac\ \-classpath\ \\examples;\\lib\\Banners.jar\ ^
-\ \ \ \ \ \ \ \ \ \ \ \ \\examples\\greetings\\Hi.java
-\f[R]
-.fi
-.PP
-To execute a class in the \f[CB]greetings\f[R] package, the program needs
-access to the \f[CB]greetings\f[R] package, and to the classes that the
-\f[CB]greetings\f[R] classes use.
-.PP
-\f[B]Oracle Solaris, Linux, and OS X:\f[R]
-.RS
-.PP
-\f[CB]java\ \-classpath\ /examples:/lib/Banners.jar\ greetings.Hi\f[R]
-.RE
-.PP
-\f[B]Windows:\f[R]
-.RS
-.PP
-\f[CB]C:\\>java\ \-classpath\ \\examples;\\lib\\Banners.jar\ greetings.Hi\f[R]
-.RE
-.PP
-The \f[CB]\-source\ 1.7\f[R] option specifies that release 1.7 (or 7) of
-the Java programming language must be used to compile OldCode.java.
-The \f[CB]\-target\ 1.7\f[R] option ensures that the generated class files
-are compatible with JVM 1.7.
-.SH ANNOTATION PROCESSING
-.PP
-The \f[CB]javac\f[R] command provides direct support for annotation
-processing, superseding the need for the separate annotation processing
-command, \f[CB]apt\f[R].
-.PP
-The API for annotation processors is defined in the
-\f[CB]javax.annotation.processing\f[R] and \f[CB]javax.lang.model\f[R]
-packages and subpackages.
-.SS How Annotation Processing Works
-.PP
-Unless annotation processing is disabled with the \f[CB]\-proc:none\f[R]
-option, the compiler searches for any annotation processors that are
-available.
-The search path can be specified with the \f[CB]\-processorpath\f[R]
-option.
-If no path is specified, then the user class path is used.
-Processors are located by means of service provider\-configuration files
-named \f[CB]META\-INF/services/javax.annotation.processing\f[R].
-Processor on the search path.
-Such files should contain the names of any annotation processors to be
-used, listed one per line.
-Alternatively, processors can be specified explicitly, using the
-\f[CB]\-processor\f[R] option.
-.PP
-After scanning the source files and classes on the command line to
-determine what annotations are present, the compiler queries the
-processors to determine what annotations they process.
-When a match is found, the processor is called.
-A processor can claim the annotations it processes, in which case no
-further attempt is made to find any processors for those annotations.
-After all of the annotations are claimed, the compiler does not search
-for additional processors.
-.PP
-If any processors generate new source files, then another round of
-annotation processing occurs: Any newly generated source files are
-scanned, and the annotations processed as before.
-Any processors called on previous rounds are also called on all
-subsequent rounds.
-This continues until no new source files are generated.
-.PP
-After a round occurs where no new source files are generated, the
-annotation processors are called one last time, to give them a chance to
-complete any remaining work.
-Finally, unless the \f[CB]\-proc:only\f[R] option is used, the compiler
-compiles the original and all generated source files.
-.SH SEARCHING FOR TYPES
-.PP
-To compile a source file, the compiler often needs information about a
-type, but the type definition is not in the source files specified on
-the command line.
-.PP
-The compiler needs type information for every class or interface used,
-extended, or implemented in the source file.
-This includes classes and interfaces not explicitly mentioned in the
-source file, but that provide information through inheritance.
-.PP
-For example, when you create a subclass of \f[CB]java.awt.Window\f[R], you
-are also using the ancestor classes of \f[CB]Window\f[R]:
-\f[CB]java.awt.Container\f[R], \f[CB]java.awt.Component\f[R], and
-\f[CB]java.lang.Object\f[R].
-.PP
-When the compiler needs type information, it searches for a source file
-or class file that defines the type.
-The compiler searches for class files first in the bootstrap and
-extension classes, then in the user class path (which by default is the
-current directory).
-The user class path is defined by setting the \f[CB]CLASSPATH\f[R]
-environment variable or by using the \f[CB]\-classpath\f[R] option.
-.PP
-If you set the \f[CB]\-sourcepath\f[R] option, then the compiler searches
-the indicated path for source files.
-Otherwise, the compiler searches the user class path for both class
-files and source files.
-.PP
-You can specify different bootstrap or extension classes with the
-\f[CB]\-bootclasspath\f[R] and the \f[CB]\-extdirs\f[R] options.
-See \f[B]Cross\-Compilation Options for javac\f[R].
-.PP
-A successful type search may produce a class file, a source file, or
-both.
-If both are found, then you can use the \f[CB]\-Xprefer\f[R] option to
-instruct the compiler which to use.
-If \f[CB]newer\f[R] is specified, then the compiler uses the newer of the
-two files.
-If \f[CB]source\f[R] is specified, the compiler uses the source file.
-The default is \f[CB]newer\f[R].
-.PP
-If a type search finds a source file for a required type, either by
-itself, or as a result of the setting for the \f[CB]\-Xprefer\f[R] option,
-then the compiler reads the source file to get the information it needs.
-By default the compiler also compiles the source file.
-You can use the \f[CB]\-implicit\f[R] option to specify the behavior.
-If \f[CB]none\f[R] is specified, then no class files are generated for the
-source file.
-If \f[CB]class\f[R] is specified, then class files are generated for the
-source file.
-.PP
-The compiler might not discover the need for some type information until
-after annotation processing completes.
-When the type information is found in a source file and no
-\f[CB]\-implicit\f[R] option is specified, the compiler gives a warning
-that the file is being compiled without being subject to annotation
-processing.
-To disable the warning, either specify the file on the command line (so
-that it will be subject to annotation processing) or use the
-\f[CB]\-implicit\f[R] option to specify whether or not class files should
-be generated for such source files.
--- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java Mon Jul 22 11:08:27 2019 +0530
@@ -72,6 +72,9 @@
// public key, if initialized for verifying
private ECPublicKey publicKey;
+ // signature parameters
+ private ECParameterSpec sigParams = null;
+
// The format. true for the IEEE P1363 format. false (default) for ASN.1
private final boolean p1363Format;
@@ -279,10 +282,14 @@
@Override
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
- this.publicKey = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
+ ECPublicKey key = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
+ if (!isCompatible(this.sigParams, key.getParams())) {
+ throw new InvalidKeyException("Key params does not match signature params");
+ }
// Should check that the supplied key is appropriate for signature
// algorithm (e.g. P-256 for SHA256withECDSA)
+ this.publicKey = key;
this.privateKey = null;
resetDigest();
}
@@ -298,10 +305,14 @@
@Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
- this.privateKey = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
+ ECPrivateKey key = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
+ if (!isCompatible(this.sigParams, key.getParams())) {
+ throw new InvalidKeyException("Key params does not match signature params");
+ }
// Should check that the supplied key is appropriate for signature
// algorithm (e.g. P-256 for SHA256withECDSA)
+ this.privateKey = key;
this.publicKey = null;
this.random = random;
resetDigest();
@@ -354,6 +365,16 @@
needsReset = true;
}
+ private static boolean isCompatible(ECParameterSpec sigParams,
+ ECParameterSpec keyParams) {
+ if (sigParams == null) {
+ // no restriction on key param
+ return true;
+ }
+ return ECUtil.equals(sigParams, keyParams);
+ }
+
+
private byte[] signDigestImpl(ECDSAOperations ops, int seedBits,
byte[] digest, ECPrivateKeyImpl privImpl, SecureRandom random)
throws SignatureException {
@@ -495,9 +516,16 @@
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
- if (params != null) {
+ if (params != null && !(params instanceof ECParameterSpec)) {
throw new InvalidAlgorithmParameterException("No parameter accepted");
}
+ ECKey key = (this.privateKey == null? this.publicKey : this.privateKey);
+ if ((key != null) && !isCompatible((ECParameterSpec)params, key.getParams())) {
+ throw new InvalidAlgorithmParameterException
+ ("Signature params does not match key params");
+ }
+
+ sigParams = (ECParameterSpec) params;
}
// get parameter, not supported. See JCA doc
@@ -510,7 +538,17 @@
@Override
protected AlgorithmParameters engineGetParameters() {
- return null;
+ if (sigParams == null) {
+ return null;
+ }
+ try {
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
+ ap.init(sigParams);
+ return ap;
+ } catch (Exception e) {
+ // should never happen
+ throw new ProviderException("Error retrieving EC parameters", e);
+ }
}
/**
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Mon Jul 22 11:08:27 2019 +0530
@@ -46,37 +46,59 @@
}
private static boolean commonHelp(String mode) {
+ return commonHelp(mode, false);
+ }
+
+ private static boolean commonHelpWithConnect(String mode) {
+ return commonHelp(mode, true);
+ }
+
+ private static boolean commonHelp(String mode, boolean canConnectToRemote) {
// --pid <pid>
// --exe <exe>
// --core <core>
- System.out.println(" --pid <pid> \tTo attach to and operate on the given live process.");
- System.out.println(" --core <corefile>\tTo operate on the given core file.");
+ // --connect [<id>@]<host>
+ System.out.println(" --pid <pid> To attach to and operate on the given live process.");
+ System.out.println(" --core <corefile> To operate on the given core file.");
System.out.println(" --exe <executable for corefile>");
+ if (canConnectToRemote) {
+ System.out.println(" --connect [<id>@]<host> To connect to a remote debug server (debugd).");
+ }
System.out.println();
System.out.println(" The --core and --exe options must be set together to give the core");
- System.out.println(" file, and associated executable, to operate on. Otherwise the --pid");
- System.out.println(" option can be set to operate on a live process.");
- System.out.println(" The arguments for --exe and --core can use absolute or relative paths.");
+ System.out.println(" file, and associated executable, to operate on. They can use");
+ System.out.println(" absolute or relative paths.");
+ System.out.println(" The --pid option can be set to operate on a live process.");
+ if (canConnectToRemote) {
+ System.out.println(" The --connect option can be set to connect to a debug server (debugd).");
+ System.out.println(" --core, --pid, and --connect are mutually exclusive.");
+ } else {
+ System.out.println(" --core and --pid are mutually exclusive.");
+ }
System.out.println();
System.out.println(" Examples: jhsdb " + mode + " --pid 1234");
System.out.println(" or jhsdb " + mode + " --core ./core.1234 --exe ./myexe");
+ if (canConnectToRemote) {
+ System.out.println(" or jhsdb " + mode + " --connect debugserver");
+ System.out.println(" or jhsdb " + mode + " --connect id@debugserver");
+ }
return false;
}
private static boolean debugdHelp() {
// [options] <pid> [server-id]
// [options] <executable> <core> [server-id]
- System.out.println(" --serverid <id> \tA unique identifier for this debug server.");
+ System.out.println(" --serverid <id> A unique identifier for this debug server.");
return commonHelp("debugd");
}
private static boolean jinfoHelp() {
// --flags -> -flags
// --sysprops -> -sysprops
- System.out.println(" --flags \tTo print VM flags.");
- System.out.println(" --sysprops \tTo print Java System properties.");
- System.out.println(" <no option> \tTo print both of the above.");
- return commonHelp("jinfo");
+ System.out.println(" --flags To print VM flags.");
+ System.out.println(" --sysprops To print Java System properties.");
+ System.out.println(" <no option> To print both of the above.");
+ return commonHelpWithConnect("jinfo");
}
private static boolean jmapHelp() {
@@ -86,27 +108,27 @@
// --clstats -> -clstats
// --finalizerinfo -> -finalizerinfo
- System.out.println(" <no option> \tTo print same info as Solaris pmap.");
- System.out.println(" --heap \tTo print java heap summary.");
- System.out.println(" --binaryheap \tTo dump java heap in hprof binary format.");
- System.out.println(" --dumpfile <name>\tThe name of the dump file.");
- System.out.println(" --histo \tTo print histogram of java object heap.");
- System.out.println(" --clstats \tTo print class loader statistics.");
- System.out.println(" --finalizerinfo \tTo print information on objects awaiting finalization.");
- return commonHelp("jmap");
+ System.out.println(" <no option> To print same info as Solaris pmap.");
+ System.out.println(" --heap To print java heap summary.");
+ System.out.println(" --binaryheap To dump java heap in hprof binary format.");
+ System.out.println(" --dumpfile <name> The name of the dump file.");
+ System.out.println(" --histo To print histogram of java object heap.");
+ System.out.println(" --clstats To print class loader statistics.");
+ System.out.println(" --finalizerinfo To print information on objects awaiting finalization.");
+ return commonHelpWithConnect("jmap");
}
private static boolean jstackHelp() {
// --locks -> -l
// --mixed -> -m
- System.out.println(" --locks \tTo print java.util.concurrent locks.");
- System.out.println(" --mixed \tTo print both Java and native frames (mixed mode).");
- return commonHelp("jstack");
+ System.out.println(" --locks To print java.util.concurrent locks.");
+ System.out.println(" --mixed To print both Java and native frames (mixed mode).");
+ return commonHelpWithConnect("jstack");
}
private static boolean jsnapHelp() {
- System.out.println(" --all \tTo print all performance counters.");
- return commonHelp("jsnap");
+ System.out.println(" --all To print all performance counters.");
+ return commonHelpWithConnect("jsnap");
}
private static boolean toolHelp(String toolName) {
@@ -134,10 +156,12 @@
return launcherHelp();
}
+ private static final String NO_REMOTE = null;
+
private static void buildAttachArgs(ArrayList<String> newArgs, String pid,
- String exe, String core, boolean allowEmpty) {
- if (!allowEmpty && (pid == null) && (exe == null)) {
- throw new SAGetoptException("You have to set --pid or --exe.");
+ String exe, String core, String remote, boolean allowEmpty) {
+ if (!allowEmpty && (pid == null) && (exe == null) && (remote == NO_REMOTE)) {
+ throw new SAGetoptException("You have to set --pid or --exe or --connect.");
}
if (pid != null) { // Attach to live process
@@ -145,13 +169,17 @@
throw new SAGetoptException("Unnecessary argument: --exe");
} else if (core != null) {
throw new SAGetoptException("Unnecessary argument: --core");
+ } else if (remote != NO_REMOTE) {
+ throw new SAGetoptException("Unnecessary argument: --connect");
} else if (!pid.matches("^\\d+$")) {
throw new SAGetoptException("Invalid pid: " + pid);
}
newArgs.add(pid);
} else if (exe != null) {
- if (exe.length() == 0) {
+ if (remote != NO_REMOTE) {
+ throw new SAGetoptException("Unnecessary argument: --connect");
+ } else if (exe.length() == 0) {
throw new SAGetoptException("You have to set --exe.");
}
@@ -162,6 +190,8 @@
}
newArgs.add(core);
+ } else if (remote != NO_REMOTE) {
+ newArgs.add(remote);
}
}
@@ -190,7 +220,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core, true);
+ buildAttachArgs(newArgs, pid, exe, core, NO_REMOTE, true);
CLHSDB.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -219,19 +249,20 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core, true);
+ buildAttachArgs(newArgs, pid, exe, core, NO_REMOTE, true);
HSDB.main(newArgs.toArray(new String[newArgs.size()]));
}
private static void runJSTACK(String[] oldArgs) {
SAGetopt sg = new SAGetopt(oldArgs);
- String[] longOpts = {"exe=", "core=", "pid=",
+ String[] longOpts = {"exe=", "core=", "pid=", "connect=",
"mixed", "locks"};
ArrayList<String> newArgs = new ArrayList();
String pid = null;
String exe = null;
String core = null;
+ String remote = NO_REMOTE;
String s = null;
while((s = sg.next(null, longOpts)) != null) {
@@ -247,6 +278,10 @@
pid = sg.getOptarg();
continue;
}
+ if (s.equals("connect")) {
+ remote = sg.getOptarg();
+ continue;
+ }
if (s.equals("mixed")) {
newArgs.add("-m");
continue;
@@ -257,20 +292,21 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core, false);
+ buildAttachArgs(newArgs, pid, exe, core, remote, false);
JStack jstack = new JStack(false, false);
jstack.runWithArgs(newArgs.toArray(new String[newArgs.size()]));
}
private static void runJMAP(String[] oldArgs) {
SAGetopt sg = new SAGetopt(oldArgs);
- String[] longOpts = {"exe=", "core=", "pid=",
+ String[] longOpts = {"exe=", "core=", "pid=", "connect=",
"heap", "binaryheap", "dumpfile=", "histo", "clstats", "finalizerinfo"};
ArrayList<String> newArgs = new ArrayList();
String pid = null;
String exe = null;
String core = null;
+ String remote = NO_REMOTE;
String s = null;
String dumpfile = null;
boolean requestHeapdump = false;
@@ -288,6 +324,10 @@
pid = sg.getOptarg();
continue;
}
+ if (s.equals("connect")) {
+ remote = sg.getOptarg();
+ continue;
+ }
if (s.equals("heap")) {
newArgs.add("-heap");
continue;
@@ -325,19 +365,20 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core, false);
+ buildAttachArgs(newArgs, pid, exe, core, remote, false);
JMap.main(newArgs.toArray(new String[newArgs.size()]));
}
private static void runJINFO(String[] oldArgs) {
SAGetopt sg = new SAGetopt(oldArgs);
- String[] longOpts = {"exe=", "core=", "pid=",
+ String[] longOpts = {"exe=", "core=", "pid=", "connect=",
"flags", "sysprops"};
ArrayList<String> newArgs = new ArrayList();
String exe = null;
String pid = null;
String core = null;
+ String remote = NO_REMOTE;
String s = null;
while((s = sg.next(null, longOpts)) != null) {
@@ -353,6 +394,10 @@
pid = sg.getOptarg();
continue;
}
+ if (s.equals("connect")) {
+ remote = sg.getOptarg();
+ continue;
+ }
if (s.equals("flags")) {
newArgs.add("-flags");
continue;
@@ -363,18 +408,19 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core, false);
+ buildAttachArgs(newArgs, pid, exe, core, remote, false);
JInfo.main(newArgs.toArray(new String[newArgs.size()]));
}
private static void runJSNAP(String[] oldArgs) {
SAGetopt sg = new SAGetopt(oldArgs);
- String[] longOpts = {"exe=", "core=", "pid=", "all"};
+ String[] longOpts = {"exe=", "core=", "pid=", "connect=", "all"};
ArrayList<String> newArgs = new ArrayList();
String exe = null;
String pid = null;
String core = null;
+ String remote = NO_REMOTE;
String s = null;
while((s = sg.next(null, longOpts)) != null) {
@@ -390,13 +436,17 @@
pid = sg.getOptarg();
continue;
}
+ if (s.equals("connect")) {
+ remote = sg.getOptarg();
+ continue;
+ }
if (s.equals("all")) {
newArgs.add("-a");
continue;
}
}
- buildAttachArgs(newArgs, pid, exe, core, false);
+ buildAttachArgs(newArgs, pid, exe, core, remote, false);
JSnap.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -436,7 +486,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core, false);
+ buildAttachArgs(newArgs, pid, exe, core, NO_REMOTE, false);
if (serverid != null) {
newArgs.add(serverid);
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciEnv.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciEnv.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,14 +50,12 @@
factoryField = type.getAddressField("_factory");
compilerDataField = type.getAddressField("_compiler_data");
taskField = type.getAddressField("_task");
- systemDictionaryModificationCounterField = new CIntField(type.getCIntegerField("_system_dictionary_modification_counter"), 0);
}
private static AddressField dependenciesField;
private static AddressField factoryField;
private static AddressField compilerDataField;
private static AddressField taskField;
- private static CIntField systemDictionaryModificationCounterField;
public ciEnv(Address addr) {
super(addr);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMOps.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMOps.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,6 @@
G1IncCollectionPause,
G1Concurrent,
EnableBiasedLocking,
- RevokeBias,
BulkRevokeBias,
PopulateDumpSharedSpace,
JNIFunctionTableCopier,
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Mon Jul 22 11:08:27 2019 +0530
@@ -1098,10 +1098,15 @@
private void writeSymbol(Symbol sym) throws IOException {
// If name is already written don't write it again.
if (names.add(sym)) {
- byte[] buf = sym.asString().getBytes("UTF-8");
- writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
- writeSymbolID(sym);
- out.write(buf);
+ if(sym != null) {
+ byte[] buf = sym.asString().getBytes("UTF-8");
+ writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
+ writeSymbolID(sym);
+ out.write(buf);
+ } else {
+ writeHeader(HPROF_UTF8, 0 + OBJ_ID_SIZE);
+ writeSymbolID(null);
+ }
}
}
@@ -1152,7 +1157,8 @@
private void writeSymbolID(Symbol sym) throws IOException {
assert names.contains(sym);
- writeObjectID(getAddressValue(sym.getAddress()));
+ long address = (sym != null) ? getAddressValue(sym.getAddress()) : getAddressValue(null);
+ writeObjectID(address);
}
private void writeObjectID(long address) throws IOException {
--- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpServer.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpServer.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -206,6 +206,10 @@
* '/'. <p>
* The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
* to HttpContext instances.
+ * @apiNote The path should generally, but is not required to, end with '/'. If the path does not
+ * end with '/', eg such as with {@code "/foo"} then this would match requests with a path of
+ * {@code "/foobar"} or {@code "/foo/bar"}.
+ *
* @param path the root URI path to associate the context with
* @param handler the handler to invoke for incoming requests.
* @throws IllegalArgumentException if path is invalid, or if a context
@@ -227,6 +231,10 @@
* '/'. <p>
* The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
* to HttpContext instances.
+ * @apiNote The path should generally, but is not required to, end with '/'. If the path does not
+ * end with '/', eg such as with {@code "/foo"} then this would match requests with a path of
+ * {@code "/foobar"} or {@code "/foo/bar"}.
+ *
* @param path the root URI path to associate the context with
* @throws IllegalArgumentException if path is invalid, or if a context
* already exists for this path
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -475,7 +475,9 @@
methodData = new HotSpotMethodData(metaspaceMethodData, this);
String methodDataFilter = Option.TraceMethodDataFilter.getString();
if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) {
- System.out.println(methodData.toString());
+ String line = methodData.toString() + System.lineSeparator();
+ byte[] lineBytes = line.getBytes();
+ CompilerToVM.compilerToVM().writeDebugOutput(lineBytes, 0, lineBytes.length, true, true);
}
}
}
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Mon Jul 22 11:08:27 2019 +0530
@@ -837,10 +837,8 @@
// Primitive type resolution is context free.
return true;
}
- if (elementType.getName().startsWith("Ljava/")) {
- // Classes in a java.* package can only be defined by the
- // boot class loader. This is enforced by ClassLoader.preDefineClass()
- assert hasSameClassLoader(runtime().getJavaLangObject());
+ if (elementType.getName().startsWith("Ljava/") && hasSameClassLoader(runtime().getJavaLangObject())) {
+ // Classes in a java.* package defined by the boot class loader are always resolved.
return true;
}
HotSpotResolvedObjectTypeImpl otherMirror = ((HotSpotResolvedObjectTypeImpl) accessingClass);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Mon Jul 22 11:08:27 2019 +0530
@@ -344,6 +344,7 @@
public final int threadIsMethodHandleReturnOffset = getFieldOffset("JavaThread::_is_method_handle_return", Integer.class, "int");
public final int threadObjectResultOffset = getFieldOffset("JavaThread::_vm_result", Integer.class, "oop");
public final int jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
+ public final int doingUnsafeAccessOffset = getFieldOffset("JavaThread::_doing_unsafe_access", Integer.class, "bool", Integer.MAX_VALUE);
public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset;
public boolean requiresReservedStackCheck(List<ResolvedJavaMethod> methods) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Jul 22 11:08:27 2019 +0530
@@ -175,7 +175,7 @@
registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
registerCounterModePlugins(invocationPlugins, config, replacementBytecodeProvider);
registerBase64Plugins(invocationPlugins, config, metaAccess, foreignCalls);
- registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider);
+ registerUnsafePlugins(invocationPlugins, config, replacementBytecodeProvider);
StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true, false);
registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
registerStringPlugins(invocationPlugins, replacementBytecodeProvider);
@@ -276,15 +276,16 @@
r.registerMethodSubstitution(ReflectionSubstitutions.class, "getClassAccessFlags", Class.class);
}
- private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementBytecodeProvider) {
+ private static void registerUnsafePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider replacementBytecodeProvider) {
Registration r;
if (JavaVersionUtil.JAVA_SPEC <= 8) {
r = new Registration(plugins, Unsafe.class, replacementBytecodeProvider);
} else {
r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacementBytecodeProvider);
}
- r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, "copyMemory", Receiver.class, Object.class, long.class, Object.class, long.class,
- long.class);
+ String substituteMethodName = config.doingUnsafeAccessOffset != Integer.MAX_VALUE ? "copyMemoryGuarded" : "copyMemory";
+ r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, substituteMethodName, Receiver.class, Object.class, long.class, Object.class,
+ long.class, long.class);
}
private static final LocationIdentity INSTANCE_KLASS_CONSTANTS = NamedLocationIdentity.immutable("InstanceKlass::_constants");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java Mon Jul 22 11:08:27 2019 +0530
@@ -24,12 +24,17 @@
package org.graalvm.compiler.hotspot.meta;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.doingUnsafeAccessOffset;
+
import org.graalvm.compiler.api.replacements.ClassSubstitution;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
import org.graalvm.compiler.nodes.ComputeObjectAddressNode;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.WordFactory;
@ClassSubstitution(className = {"jdk.internal.misc.Unsafe", "sun.misc.Unsafe"})
@@ -43,6 +48,24 @@
Word srcAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(srcBase, srcOffset));
Word dstAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(destBase, destOffset));
Word size = WordFactory.signed(bytes);
+
HotSpotBackend.unsafeArraycopy(srcAddr, dstAddr, size);
}
+
+ @SuppressWarnings("unused")
+ @MethodSubstitution(value = "copyMemory", isStatic = false)
+ static void copyMemoryGuarded(Object receiver, Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) {
+ Word srcAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(srcBase, srcOffset));
+ Word dstAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(destBase, destOffset));
+ Word size = WordFactory.signed(bytes);
+ Word javaThread = CurrentJavaThreadNode.get();
+ int offset = doingUnsafeAccessOffset(INJECTED_VMCONFIG);
+ LocationIdentity any = LocationIdentity.any();
+
+ /* Set doingUnsafeAccess to guard and handle unsafe memory access failures */
+ javaThread.writeByte(offset, (byte) 1, any);
+ HotSpotBackend.unsafeArraycopy(srcAddr, dstAddr, size);
+ /* Reset doingUnsafeAccess */
+ javaThread.writeByte(offset, (byte) 0, any);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Mon Jul 22 11:08:27 2019 +0530
@@ -187,6 +187,14 @@
return config.verifyOops;
}
+ /**
+ * @see GraalHotSpotVMConfig#doingUnsafeAccessOffset
+ */
+ @Fold
+ public static int doingUnsafeAccessOffset(@InjectedParameter GraalHotSpotVMConfig config) {
+ return config.doingUnsafeAccessOffset;
+ }
+
public static final LocationIdentity EXCEPTION_OOP_LOCATION = NamedLocationIdentity.mutable("ExceptionOop");
/**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,11 +29,9 @@
import static jdk.vm.ci.amd64.AMD64.rdi;
import static jdk.vm.ci.amd64.AMD64.rdx;
import static jdk.vm.ci.amd64.AMD64.rsi;
-
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
-import jdk.vm.ci.amd64.AMD64;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
@@ -44,6 +42,7 @@
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
+import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.meta.Value;
@@ -52,9 +51,13 @@
public final class AMD64StringLatin1InflateOp extends AMD64LIRInstruction {
public static final LIRInstructionClass<AMD64StringLatin1InflateOp> TYPE = LIRInstructionClass.create(AMD64StringLatin1InflateOp.class);
- @Alive({REG}) private Value rsrc;
- @Alive({REG}) private Value rdst;
- @Alive({REG}) private Value rlen;
+ @Use({REG}) private Value rsrc;
+ @Use({REG}) private Value rdst;
+ @Use({REG}) private Value rlen;
+
+ @Temp({REG}) private Value rsrcTemp;
+ @Temp({REG}) private Value rdstTemp;
+ @Temp({REG}) private Value rlenTemp;
@Temp({REG}) private Value vtmp1;
@Temp({REG}) private Value rtmp2;
@@ -66,9 +69,9 @@
assert asRegister(dst).equals(rdi);
assert asRegister(len).equals(rdx);
- rsrc = src;
- rdst = dst;
- rlen = len;
+ rsrcTemp = rsrc = src;
+ rdstTemp = rdst = dst;
+ rlenTemp = rlen = len;
vtmp1 = tool.newVariable(LIRKind.value(AMD64Kind.V512_BYTE));
rtmp2 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java Mon Jul 22 11:08:27 2019 +0530
@@ -31,12 +31,10 @@
import static jdk.vm.ci.amd64.AMD64.rdi;
import static jdk.vm.ci.amd64.AMD64.rdx;
import static jdk.vm.ci.amd64.AMD64.rsi;
-
import static jdk.vm.ci.amd64.AMD64.rsp;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
-import jdk.vm.ci.amd64.AMD64;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
@@ -47,6 +45,7 @@
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
+import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.meta.Value;
@@ -56,9 +55,13 @@
public static final LIRInstructionClass<AMD64StringUTF16CompressOp> TYPE = LIRInstructionClass.create(AMD64StringUTF16CompressOp.class);
@Def({REG}) private Value rres;
- @Alive({REG}) private Value rsrc;
- @Alive({REG}) private Value rdst;
- @Alive({REG}) private Value rlen;
+ @Use({REG}) private Value rsrc;
+ @Use({REG}) private Value rdst;
+ @Use({REG}) private Value rlen;
+
+ @Temp({REG}) private Value rsrcTemp;
+ @Temp({REG}) private Value rdstTemp;
+ @Temp({REG}) private Value rlenTemp;
@Temp({REG}) private Value vtmp1;
@Temp({REG}) private Value vtmp2;
@@ -75,9 +78,9 @@
assert asRegister(res).equals(rax);
rres = res;
- rsrc = src;
- rdst = dst;
- rlen = len;
+ rsrcTemp = rsrc = src;
+ rdstTemp = rdst = dst;
+ rlenTemp = rlen = len;
LIRKind vkind = LIRKind.value(AMD64Kind.V512_BYTE);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,7 +1,6 @@
doclet.build_version=\u6A19\u6E96Doclet\u30D0\u30FC\u30B8\u30E7\u30F3{0}
doclet.Contents=\u30B3\u30F3\u30C6\u30F3\u30C4
doclet.Overview=\u6982\u8981
-doclet.Window_Overview=\u6982\u8981\u30EA\u30B9\u30C8
doclet.Window_Overview_Summary=\u6982\u8981
doclet.Element=\u8981\u7D20
doclet.Package=\u30D1\u30C3\u30B1\u30FC\u30B8
@@ -93,6 +92,7 @@
doclet.Interfaces=\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
doclet.Enclosing_Class=\u542B\u307E\u308C\u3066\u3044\u308B\u30AF\u30E9\u30B9:
doclet.Enclosing_Interface=\u542B\u307E\u308C\u3066\u3044\u308B\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9:
+doclet.Inheritance_Tree=\u7D99\u627F\u30C4\u30EA\u30FC
doclet.System_Property=\u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3
doclet.Window_Source_title=\u30BD\u30FC\u30B9\u30FB\u30B3\u30FC\u30C9
doclet.Window_Help_title=API\u30D8\u30EB\u30D7
@@ -121,8 +121,6 @@
doclet.help.deprecated.body={0}\u30DA\u30FC\u30B8\u306F\u3001\u63A8\u5968\u3055\u308C\u3066\u3044\u306A\u3044\u3059\u3079\u3066\u306EAPI\u306E\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059\u3002\u975E\u63A8\u5968API\u3068\u306F\u3001\u6A5F\u80FD\u6539\u826F\u306A\u3069\u306E\u7406\u7531\u304B\u3089\u4F7F\u7528\u3092\u304A\u85A6\u3081\u3067\u304D\u306A\u304F\u306A\u3063\u305FAPI\u306E\u3053\u3068\u3067\u3001\u901A\u5E38\u306F\u305D\u308C\u306B\u4EE3\u308F\u308BAPI\u304C\u63D0\u4F9B\u3055\u308C\u307E\u3059\u3002\u975E\u63A8\u5968API\u306F\u4ECA\u5F8C\u306E\u5B9F\u88C5\u3067\u524A\u9664\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002
doclet.help.index.head=\u7D22\u5F15
doclet.help.index.body={0}\u306B\u306F\u3001\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3001\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3001\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u3001\u30E1\u30BD\u30C3\u30C9\u304A\u3088\u3073\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u30A2\u30EB\u30D5\u30A1\u30D9\u30C3\u30C8\u9806\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3068\u3001\u3059\u3079\u3066\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u304A\u3088\u3073\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u306E\u30EA\u30B9\u30C8\u304C\u542B\u307E\u308C\u307E\u3059\u3002
-doclet.help.frames.head=\u30D5\u30EC\u30FC\u30E0/\u30D5\u30EC\u30FC\u30E0\u306A\u3057
-doclet.help.frames.body=\u3053\u308C\u3089\u306E\u30EA\u30F3\u30AF\u306FHTML\u30D5\u30EC\u30FC\u30E0\u306E\u8868\u793A\u3068\u975E\u8868\u793A\u3092\u5207\u308A\u66FF\u3048\u307E\u3059\u3002\u3059\u3079\u3066\u306E\u30DA\u30FC\u30B8\u306F\u30D5\u30EC\u30FC\u30E0\u3042\u308A\u3067\u3082\u3001\u30D5\u30EC\u30FC\u30E0\u306A\u3057\u3067\u3082\u8868\u793A\u3067\u304D\u307E\u3059\u3002
doclet.help.serial_form.body=\u76F4\u5217\u5316\u53EF\u80FD\u307E\u305F\u306F\u5916\u90E8\u5316\u53EF\u80FD\u306A\u5404\u30AF\u30E9\u30B9\u306F\u3001\u76F4\u5217\u5316\u30D5\u30A3\u30FC\u30EB\u30C9\u3068\u30E1\u30BD\u30C3\u30C9\u306E\u8AAC\u660E\u3092\u542B\u307F\u307E\u3059\u3002\u3053\u306E\u60C5\u5831\u306F\u3001API\u3092\u4F7F\u7528\u3059\u308B\u958B\u767A\u8005\u3067\u306F\u306A\u304F\u3001\u518D\u5B9F\u88C5\u3092\u884C\u3046\u62C5\u5F53\u8005\u306B\u5F79\u7ACB\u3061\u307E\u3059\u3002\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u306B\u30EA\u30F3\u30AF\u304C\u306A\u3044\u5834\u5408\u3001\u76F4\u5217\u5316\u3055\u308C\u305F\u30AF\u30E9\u30B9\u306B\u79FB\u52D5\u3057\u3066\u3001\u30AF\u30E9\u30B9\u8A18\u8FF0\u306E\u300C\u95A2\u9023\u9805\u76EE\u300D\u30BB\u30AF\u30B7\u30E7\u30F3\u306B\u3042\u308B\u300C\u76F4\u5217\u5316\u3055\u308C\u305F\u5F62\u5F0F\u300D\u3092\u30AF\u30EA\u30C3\u30AF\u3059\u308B\u3053\u3068\u306B\u3088\u308A\u3001\u3053\u306E\u60C5\u5831\u3092\u8868\u793A\u3067\u304D\u307E\u3059\u3002
doclet.help.constants.body={0}\u30DA\u30FC\u30B8\u306B\u306F\u3001static final\u30D5\u30A3\u30FC\u30EB\u30C9\u3068\u305D\u306E\u5024\u306E\u30EA\u30B9\u30C8\u304C\u3042\u308A\u307E\u3059\u3002
doclet.help.footnote=\u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30D5\u30A1\u30A4\u30EB\u306F\u3001\u6A19\u6E96doclet\u306B\u3088\u3063\u3066\u751F\u6210\u3055\u308C\u305FAPI\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306B\u9069\u7528\u3055\u308C\u307E\u3059\u3002
@@ -196,9 +194,7 @@
doclet.usage.header.parameters=<html-code>
doclet.usage.header.description=\u5404\u30DA\u30FC\u30B8\u306B\u30D8\u30C3\u30C0\u30FC\u30FB\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u307E\u3059
-doclet.usage.html4.description=HTML 4.01\u51FA\u529B\u3092\u751F\u6210\u3057\u307E\u3059
-
-doclet.usage.html5.description=HTML 5\u51FA\u529B\u3092\u751F\u6210\u3057\u307E\u3059
+doclet.usage.html5.description=HTML 5\u51FA\u529B\u3092\u751F\u6210\u3057\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5FC5\u9808\u3067\u306F\u306A\u304F\u306A\u308A\u307E\u3057\u305F\u3002
doclet.usage.footer.parameters=<html-code>
doclet.usage.footer.description=\u5404\u30DA\u30FC\u30B8\u306B\u30D5\u30C3\u30BF\u30FC\u30FB\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u307E\u3059
@@ -298,8 +294,5 @@
doclet.usage.xdoclint-package.parameters=([-]<packages>)
doclet.usage.xdoclint-package.description=\u7279\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002<packages>\u306F\n\u30AB\u30F3\u30DE\u3067\u533A\u5207\u3089\u308C\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\n\u6307\u5B9A\u5B50\u306F\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u3001\u307E\u305F\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\n\u306E\u63A5\u982D\u8F9E\u306E\u5F8C\u306B.*\u3092\u6307\u5B9A(\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u3059\u3079\u3066\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\n\u306B\u62E1\u5F35)\u3057\u305F\u3082\u306E\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u524D\u306B-\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\n\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u95A2\u3059\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u7121\u52B9\u306B\u3067\u304D\u307E\u3059\u3002
-# L10N: do not localize the option names -html4 and -html5
-doclet.HTML_4_specified=-html4\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066HTML\u30D0\u30FC\u30B8\u30E7\u30F3\u306BHTML 4.01\u3092\u6307\u5B9A\u3057\u307E\u3057\u305F\u3002\n\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u73FE\u5728HTML5\u3067\u3001HTML 4.01\u306E\u30B5\u30DD\u30FC\u30C8\u306F\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\n\u524A\u9664\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u8B66\u544A\u3092\u8868\u793A\u3057\u306A\u3044\u3088\u3046\u306B\u3059\u308B\u306B\u306F\u3001\u30B3\u30E1\u30F3\u30C8\u306EHTML\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30C8\u304C\nHTML5\u3067\u6709\u52B9\u3067\u3042\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3057\u3001-html4\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u524A\u9664\u3057\u3066\u304F\u3060\u3055\u3044\u3002
-
-# L10N: do not localize the option names --frames
-doclet.Frames_specified=--frames\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u3001\u30D5\u30EC\u30FC\u30E0\u306E\u751F\u6210\u3092\u6307\u5B9A\u3057\u307E\u3057\u305F\u3002\n\u73FE\u5728\u3001\u30D5\u30EC\u30FC\u30E0\u3092\u751F\u6210\u3057\u306A\u3044\u306E\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u3042\u308A\u3001\u30D5\u30EC\u30FC\u30E0\u306E\n\u30B5\u30DD\u30FC\u30C8\u306F\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u307E\u3059\u3002\n\u3053\u306E\u8B66\u544A\u3092\u8868\u793A\u3057\u306A\u3044\u3088\u3046\u306B\u3059\u308B\u306B\u306F\u3001--frames\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u524A\u9664\u3057\u3001\u30D5\u30EC\u30FC\u30E0\u306E\u4F7F\u7528\u3092\u907F\u3051\u3066\u304F\u3060\u3055\u3044\u3002
+# L10N: do not localize the option names --no-frames
+doclet.NoFrames_specified=--no-frames\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5FC5\u9808\u3067\u306F\u306A\u304F\u306A\u308A\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\n\u524A\u9664\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,7 +1,6 @@
doclet.build_version=\u6807\u51C6 Doclet \u7248\u672C {0}
doclet.Contents=\u76EE\u5F55
doclet.Overview=\u6982\u89C8
-doclet.Window_Overview=\u6982\u89C8\u5217\u8868
doclet.Window_Overview_Summary=\u6982\u89C8
doclet.Element=\u5143\u7D20
doclet.Package=\u7A0B\u5E8F\u5305
@@ -93,6 +92,7 @@
doclet.Interfaces=\u63A5\u53E3
doclet.Enclosing_Class=\u5C01\u95ED\u7C7B:
doclet.Enclosing_Interface=\u5C01\u95ED\u63A5\u53E3:
+doclet.Inheritance_Tree=\u7EE7\u627F\u6811
doclet.System_Property=\u7CFB\u7EDF\u5C5E\u6027
doclet.Window_Source_title=\u6E90\u4EE3\u7801
doclet.Window_Help_title=API \u5E2E\u52A9
@@ -121,8 +121,6 @@
doclet.help.deprecated.body={0} \u9875\u9762\u5217\u51FA\u4E86\u6240\u6709\u5DF2\u8FC7\u65F6\u7684 API\u3002\u4E00\u822C\u7531\u4E8E\u8FDB\u884C\u4E86\u6539\u8FDB\u5E76\u4E14\u901A\u5E38\u63D0\u4F9B\u4E86\u66FF\u4EE3\u7684 API, \u6240\u4EE5\u5EFA\u8BAE\u4E0D\u8981\u4F7F\u7528\u5DF2\u8FC7\u65F6\u7684 API\u3002\u5728\u5C06\u6765\u7684\u5B9E\u73B0\u8FC7\u7A0B\u4E2D, \u53EF\u80FD\u4F1A\u5220\u9664\u5DF2\u8FC7\u65F6\u7684 API\u3002
doclet.help.index.head=\u7D22\u5F15
doclet.help.index.body={0} \u5305\u542B\u6240\u6709\u7C7B\u3001\u63A5\u53E3\u3001\u6784\u9020\u5668\u3001\u65B9\u6CD5\u548C\u5B57\u6BB5\u7684\u6309\u5B57\u6BCD\u987A\u5E8F\u6392\u5217\u7684\u7D22\u5F15\uFF0C\u4EE5\u53CA\u6240\u6709\u7A0B\u5E8F\u5305\u548C\u6240\u6709\u7C7B\u7684\u5217\u8868\u3002
-doclet.help.frames.head=\u6846\u67B6/\u65E0\u6846\u67B6
-doclet.help.frames.body=\u8FD9\u4E9B\u94FE\u63A5\u7528\u4E8E\u663E\u793A\u548C\u9690\u85CF HTML \u6846\u67B6\u3002\u6240\u6709\u9875\u9762\u5747\u5177\u6709\u6709\u6846\u67B6\u548C\u65E0\u6846\u67B6\u4E24\u79CD\u663E\u793A\u65B9\u5F0F\u3002
doclet.help.serial_form.body=\u6BCF\u4E2A\u53EF\u5E8F\u5217\u5316\u6216\u53EF\u5916\u90E8\u5316\u7684\u7C7B\u90FD\u6709\u5176\u5E8F\u5217\u5316\u5B57\u6BB5\u548C\u65B9\u6CD5\u7684\u8BF4\u660E\u3002\u6B64\u4FE1\u606F\u5BF9\u91CD\u65B0\u5B9E\u73B0\u8005\u6709\u7528, \u800C\u5BF9\u4F7F\u7528 API \u7684\u5F00\u53D1\u8005\u5219\u6CA1\u6709\u4EC0\u4E48\u7528\u5904\u3002\u5C3D\u7BA1\u5BFC\u822A\u680F\u4E2D\u6CA1\u6709\u94FE\u63A5, \u4F46\u60A8\u53EF\u4EE5\u901A\u8FC7\u4E0B\u5217\u65B9\u5F0F\u83B7\u53D6\u6B64\u4FE1\u606F: \u8F6C\u81F3\u4EFB\u4F55\u5E8F\u5217\u5316\u7C7B, \u7136\u540E\u5355\u51FB\u7C7B\u8BF4\u660E\u7684 "\u53E6\u8BF7\u53C2\u9605" \u90E8\u5206\u4E2D\u7684 "\u5E8F\u5217\u5316\u8868\u683C"\u3002
doclet.help.constants.body={0}\u9875\u9762\u5217\u51FA\u4E86\u9759\u6001\u6700\u7EC8\u5B57\u6BB5\u53CA\u5176\u503C\u3002
doclet.help.footnote=\u6B64\u5E2E\u52A9\u6587\u4EF6\u9002\u7528\u4E8E\u7531\u6807\u51C6 doclet \u751F\u6210\u7684 API \u6587\u6863\u3002
@@ -196,9 +194,7 @@
doclet.usage.header.parameters=<html-code>
doclet.usage.header.description=\u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u7709\u6587\u672C
-doclet.usage.html4.description=\u751F\u6210 HTML 4.01 \u8F93\u51FA
-
-doclet.usage.html5.description=\u751F\u6210 HTML 5 \u8F93\u51FA
+doclet.usage.html5.description=\u751F\u6210 HTML 5 \u8F93\u51FA\u3002\u6B64\u9009\u9879\u4E0D\u518D\u662F\u5FC5\u9700\u7684\u3002
doclet.usage.footer.parameters=<html-code>
doclet.usage.footer.description=\u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u811A\u6587\u672C
@@ -298,8 +294,5 @@
doclet.usage.xdoclint-package.parameters=([-]<packages>)
doclet.usage.xdoclint-package.description=\u5728\u7279\u5B9A\u7684\u7A0B\u5E8F\u5305\u4E2D\u542F\u7528\u6216\u7981\u7528\u68C0\u67E5\u3002<\u7A0B\u5E8F\u5305>\n\u662F\u9017\u53F7\u5206\u9694\u7684\u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u5217\u8868\u3002\u7A0B\u5E8F\u5305\n\u8BF4\u660E\u7B26\u662F\u7A0B\u5E8F\u5305\u7684\u9650\u5B9A\u540D\u79F0\u6216\u7A0B\u5E8F\u5305\u540D\u79F0\n\u524D\u7F00\u540E\u8DDF .*, \u5B83\u6269\u5C55\u5230\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u7684\u6240\u6709\n\u5B50\u7A0B\u5E8F\u5305\u3002\u5728\u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u524D\u9762\u52A0\u4E0A - \u53EF\u4EE5\n\u4E3A\u6307\u5B9A\u7A0B\u5E8F\u5305\u7981\u7528\u68C0\u67E5\u3002
-# L10N: do not localize the option names -html4 and -html5
-doclet.HTML_4_specified=\u60A8\u5DF2\u4F7F\u7528 -html4 \u9009\u9879\u5C06 HTML \u7248\u672C\u6307\u5B9A\u4E3A HTML 4.01\u3002\n\u9ED8\u8BA4\u503C\u5F53\u524D\u4E3A HTML5\uFF0C\u672A\u6765\u7684\u53D1\u884C\u7248\u4E2D\u5C06\u5220\u9664\u5BF9 \nHTML 4.01 \u7684\u652F\u6301\u3002\u8981\u9690\u85CF\u6B64\u8B66\u544A\uFF0C\u8BF7\u786E\u4FDD\u60A8\u7684\u6CE8\u91CA\u4E2D\u4F7F\u7528\u7684\u4EFB\u4F55 HTML \u7ED3\u6784\n\u5728 HTML5 \u4E2D\u5747\u6709\u6548\u5E76\u5220\u9664 -html4 \u9009\u9879\u3002
-
-# L10N: do not localize the option names --frames
-doclet.Frames_specified=\u60A8\u5DF2\u6307\u5B9A\u901A\u8FC7\u4F7F\u7528 --frames \u9009\u9879\u751F\u6210\u5E27\u3002\n\u9ED8\u8BA4\u8BBE\u7F6E\u5F53\u524D\u4E3A\u4E0D\u751F\u6210\u5E27\uFF0C\u5BF9\u5E27\u7684\u652F\u6301\n\u5C06\u5728\u672A\u6765\u7684\u53D1\u884C\u7248\u4E2D\u5220\u9664\u3002\n\u8981\u9690\u85CF\u6B64\u8B66\u544A\uFF0C\u8BF7\u5220\u9664 --frames \u9009\u9879\u5E76\u907F\u514D\u4F7F\u7528\u5E27\u3002
+# L10N: do not localize the option names --no-frames
+doclet.NoFrames_specified=--no-frames \u9009\u9879\u4E0D\u518D\u662F\u5FC5\u9700\u7684\uFF0C\u53EF\u80FD\n\u4F1A\u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664\u6B64\u9009\u9879\u3002
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -47,6 +47,8 @@
doclet.Notice_taglet_conflict_warn=\u6CE8\u610F: \u6A19\u6E96\u30BF\u30B0\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\u53EF\u80FD\u6027\u306E\u3042\u308B\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0: {0}\u3002\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3092\u907F\u3051\u308B\u305F\u3081\u306B\u3001\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u540D\u306E\u4E2D\u306B\u5C11\u306A\u304F\u3068\u30821\u3064\u306E\u30D4\u30EA\u30AA\u30C9(.)\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
doclet.Error_taglet_not_registered=\u30A8\u30E9\u30FC - \u30BF\u30B0\u30EC\u30C3\u30C8{1}\u3092\u767B\u9332\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u308B\u3068\u304D\u306B\u3001\u4F8B\u5916{0}\u304C\u30B9\u30ED\u30FC\u3055\u308C\u307E\u3057\u305F...
doclet.Error_invalid_custom_tag_argument=\u30A8\u30E9\u30FC - {0}\u306F-tag\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u5BFE\u3057\u3066\u7121\u52B9\u306A\u5F15\u6570\u3067\u3059...
+doclet.taglet_could_not_set_location = \u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30D1\u30B9: {0}\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
+doclet.not_standard_file_manager = \u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30D1\u30B9\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CD\u30FC\u30B8\u30E3\u304CStandardJavaFileManager\u3067\u306F\u3042\u308A\u307E\u305B\u3093
doclet.Author=\u4F5C\u6210\u8005:
doclet.DefaultValue=\u30C7\u30D5\u30A9\u30EB\u30C8\u5024:
doclet.PropertyDescription=\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u8AAC\u660E:
@@ -85,10 +87,8 @@
doclet.Opened_Packages_Summary=\u30AA\u30FC\u30D7\u30F3
doclet.Concealed_Packages_Summary=\u975E\u8868\u793A
doclet.From=\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u5143
-doclet.Packages_Summary=\u30D1\u30C3\u30B1\u30FC\u30B8
doclet.Uses_Summary=\u4F7F\u7528
doclet.Provides_Summary=\u63D0\u4F9B
-doclet.Module_Summary=\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u6982\u8981
doclet.Interface_Summary=\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306E\u6982\u8981
doclet.Annotation_Types_Summary=\u6CE8\u91C8\u578B\u306E\u6982\u8981
doclet.Enum_Summary=\u5217\u6319\u578B\u306E\u6982\u8981
@@ -111,12 +111,9 @@
doclet.Classes=\u30AF\u30E9\u30B9
doclet.packages=\u30D1\u30C3\u30B1\u30FC\u30B8
doclet.modules=\u30E2\u30B8\u30E5\u30FC\u30EB
-doclet.types=\u30BF\u30A4\u30D7
doclet.All_Classes=\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9
doclet.All_Superinterfaces=\u3059\u3079\u3066\u306E\u30B9\u30FC\u30D1\u30FC\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9:
doclet.All_Implemented_Interfaces=\u3059\u3079\u3066\u306E\u5B9F\u88C5\u3055\u308C\u305F\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9:
-doclet.All_classes_and_interfaces=\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9(\u975Estatic\u306E\u30CD\u30B9\u30C8\u3055\u308C\u305F\u578B\u3092\u9664\u304F)
-doclet.Package_class_and_interface_descriptions=\u30D1\u30C3\u30B1\u30FC\u30B8\u3001\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306E\u8AAC\u660E
doclet.Interface=\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
doclet.Class=\u30AF\u30E9\u30B9
doclet.AnnotationType=\u6CE8\u91C8\u578B
@@ -157,7 +154,7 @@
doclet.Annotation_Type_Member_Detail=\u8981\u7D20\u306E\u8A73\u7D30
doclet.Enum_Constant_Detail=\u5217\u6319\u578B\u5B9A\u6570\u306E\u8A73\u7D30
doclet.Constants_Summary=\u5B9A\u6570\u30D5\u30A3\u30FC\u30EB\u30C9\u5024
-doclet.Field_Detail=\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u8A73\u7D30
+doclet.Field_Detail=\u30D5\u30A3\u30FC\u30EB\u30C9\u8A73\u7D30
doclet.Property_Detail=\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u8A73\u7D30
doclet.Method_Detail=\u30E1\u30BD\u30C3\u30C9\u306E\u8A73\u7D30
doclet.Constructor_Detail=\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u306E\u8A73\u7D30
@@ -170,12 +167,9 @@
doclet.dest_dir_create=\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u4F5C\u6210\u4E2D: "{0}"
doclet.in={1}\u306E{0}
doclet.Use_Table_Summary=\u8868\u3001{0}\u306E\u30EA\u30B9\u30C8\u304A\u3088\u3073\u8AAC\u660E\u306E\u4F7F\u7528
-doclet.Constants_Table_Summary={0}\u8868\u3001\u5B9A\u6570\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u30EA\u30B9\u30C8\u304A\u3088\u3073\u5024
doclet.Member_Table_Summary={0}\u8868\u3001{1}\u306E\u30EA\u30B9\u30C8\u304A\u3088\u3073\u8AAC\u660E
-doclet.Indirect_Packages_Table_Summary={0}\u8868\u3001{1}\u306E\u30EA\u30B9\u30C8\u304A\u3088\u3073{2}
doclet.fields=\u30D5\u30A3\u30FC\u30EB\u30C9
doclet.Fields=\u30D5\u30A3\u30FC\u30EB\u30C9
-doclet.properties=\u30D7\u30ED\u30D1\u30C6\u30A3
doclet.Properties=\u30D7\u30ED\u30D1\u30C6\u30A3
doclet.constructors=\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF
doclet.Constructors=\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF
@@ -188,16 +182,11 @@
doclet.Concrete_Methods=concrete\u30E1\u30BD\u30C3\u30C9
doclet.Default_Methods=\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30E1\u30BD\u30C3\u30C9
doclet.Deprecated_Methods=\u63A8\u5968\u3055\u308C\u3066\u3044\u306A\u3044\u30E1\u30BD\u30C3\u30C9
-doclet.annotation_type_optional_members=\u4EFB\u610F\u8981\u7D20
doclet.Annotation_Type_Optional_Members=\u4EFB\u610F\u8981\u7D20
-doclet.annotation_type_required_members=\u5FC5\u9808\u8981\u7D20
doclet.Annotation_Type_Required_Members=\u5FC5\u9808\u8981\u7D20
doclet.enum_constants=\u5217\u6319\u578B\u5B9A\u6570
doclet.Enum_Constants=\u5217\u6319\u5B9A\u6570
-doclet.nested_classes=\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30AF\u30E9\u30B9
doclet.Nested_Classes=\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30AF\u30E9\u30B9
-doclet.subclasses=\u30B5\u30D6\u30AF\u30E9\u30B9
-doclet.subinterfaces=\u30B5\u30D6\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
doclet.Modifier=\u4FEE\u98FE\u5B50
doclet.Type=\u30BF\u30A4\u30D7
doclet.Modifier_and_Type=\u4FEE\u98FE\u5B50\u3068\u30BF\u30A4\u30D7
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -47,6 +47,8 @@
doclet.Notice_taglet_conflict_warn=\u6CE8: \u53EF\u80FD\u8986\u76D6\u5C06\u6765\u7684\u6807\u51C6\u6807\u8BB0\u7684\u5B9A\u5236\u6807\u8BB0: {0}\u3002\u4E3A\u4E86\u907F\u514D\u51FA\u73B0\u53EF\u80FD\u7684\u8986\u76D6, \u8BF7\u5728\u5B9A\u5236\u6807\u8BB0\u540D\u79F0\u4E2D\u81F3\u5C11\u4F7F\u7528\u4E00\u4E2A\u53E5\u70B9\u5B57\u7B26 (.)\u3002
doclet.Error_taglet_not_registered=\u9519\u8BEF - \u5C1D\u8BD5\u6CE8\u518C Taglet {1}\u65F6\u629B\u51FA\u5F02\u5E38\u9519\u8BEF{0}...
doclet.Error_invalid_custom_tag_argument=\u9519\u8BEF - \u5BF9\u4E8E -tag \u9009\u9879, {0}\u662F\u65E0\u6548\u53C2\u6570...
+doclet.taglet_could_not_set_location = \u65E0\u6CD5\u8BBE\u7F6E taglet \u8DEF\u5F84\uFF1A{0}
+doclet.not_standard_file_manager = \u65E0\u6CD5\u8BBE\u7F6E taglet \u8DEF\u5F84\uFF1B\u6587\u4EF6\u7BA1\u7406\u5668\u4E0D\u662F StandardJavaFileManager
doclet.Author=\u4F5C\u8005:
doclet.DefaultValue=\u9ED8\u8BA4\u503C:
doclet.PropertyDescription=\u5C5E\u6027\u8BF4\u660E:
@@ -85,10 +87,8 @@
doclet.Opened_Packages_Summary=\u6253\u5F00\u9879
doclet.Concealed_Packages_Summary=\u5DF2\u9690\u85CF
doclet.From=\u4ECE
-doclet.Packages_Summary=\u7A0B\u5E8F\u5305
doclet.Uses_Summary=\u4F7F\u7528
doclet.Provides_Summary=\u63D0\u4F9B
-doclet.Module_Summary=\u6A21\u5757\u6982\u8981
doclet.Interface_Summary=\u63A5\u53E3\u6982\u8981
doclet.Annotation_Types_Summary=\u6CE8\u91CA\u7C7B\u578B\u6982\u8981
doclet.Enum_Summary=\u679A\u4E3E\u6982\u8981
@@ -111,12 +111,9 @@
doclet.Classes=\u7C7B
doclet.packages=\u7A0B\u5E8F\u5305
doclet.modules=\u6A21\u5757
-doclet.types=\u7C7B\u578B
doclet.All_Classes=\u6240\u6709\u7C7B
doclet.All_Superinterfaces=\u6240\u6709\u8D85\u7EA7\u63A5\u53E3:
doclet.All_Implemented_Interfaces=\u6240\u6709\u5DF2\u5B9E\u73B0\u7684\u63A5\u53E3:
-doclet.All_classes_and_interfaces=\u6240\u6709\u7C7B\u548C\u63A5\u53E3 (\u9664\u4E86\u975E\u9759\u6001\u5D4C\u5957\u7C7B\u578B)
-doclet.Package_class_and_interface_descriptions=\u7A0B\u5E8F\u5305, \u7C7B\u548C\u63A5\u53E3\u8BF4\u660E
doclet.Interface=\u63A5\u53E3
doclet.Class=\u7C7B
doclet.AnnotationType=\u6CE8\u91CA\u7C7B\u578B
@@ -158,7 +155,7 @@
doclet.Enum_Constant_Detail=\u679A\u4E3E\u5E38\u91CF\u8BE6\u7EC6\u8D44\u6599
doclet.Constants_Summary=\u5E38\u91CF\u5B57\u6BB5\u503C
doclet.Field_Detail=\u5B57\u6BB5\u8BE6\u7EC6\u8D44\u6599
-doclet.Property_Detail=\u5C5E\u6027\u8BE6\u7EC6\u4FE1\u606F
+doclet.Property_Detail=\u5C5E\u6027\u8BE6\u7EC6\u8D44\u6599
doclet.Method_Detail=\u65B9\u6CD5\u8BE6\u7EC6\u8D44\u6599
doclet.Constructor_Detail=\u6784\u9020\u5668\u8BE6\u7EC6\u8D44\u6599
doclet.Deprecated=\u5DF2\u8FC7\u65F6\u3002
@@ -170,12 +167,9 @@
doclet.dest_dir_create=\u6B63\u5728\u521B\u5EFA\u76EE\u6807\u76EE\u5F55: "{0}"
doclet.in={1}\u4E2D\u7684{0}
doclet.Use_Table_Summary=\u4F7F\u7528\u8868, \u5217\u8868{0}\u548C\u89E3\u91CA
-doclet.Constants_Table_Summary={0}\u8868, \u5217\u8868\u5E38\u91CF\u5B57\u6BB5\u548C\u503C
doclet.Member_Table_Summary={0}\u8868, \u5217\u8868{1}\u548C\u89E3\u91CA
-doclet.Indirect_Packages_Table_Summary={0} \u8868, \u5176\u4E2D\u5217\u51FA {1} \u548C {2}
doclet.fields=\u5B57\u6BB5
doclet.Fields=\u5B57\u6BB5
-doclet.properties=\u5C5E\u6027
doclet.Properties=\u5C5E\u6027
doclet.constructors=\u6784\u9020\u5668
doclet.Constructors=\u6784\u9020\u5668
@@ -188,16 +182,11 @@
doclet.Concrete_Methods=\u5177\u4F53\u65B9\u6CD5
doclet.Default_Methods=\u9ED8\u8BA4\u65B9\u6CD5
doclet.Deprecated_Methods=\u5DF2\u8FC7\u65F6\u7684\u65B9\u6CD5
-doclet.annotation_type_optional_members=\u53EF\u9009\u5143\u7D20
doclet.Annotation_Type_Optional_Members=\u53EF\u9009\u5143\u7D20
-doclet.annotation_type_required_members=\u5FC5\u9700\u7684\u5143\u7D20
doclet.Annotation_Type_Required_Members=\u6240\u9700\u5143\u7D20
doclet.enum_constants=\u679A\u4E3E\u5E38\u91CF
doclet.Enum_Constants=\u679A\u4E3E\u5E38\u91CF
-doclet.nested_classes=\u5D4C\u5957\u7C7B
doclet.Nested_Classes=\u5D4C\u5957\u7C7B
-doclet.subclasses=\u5B50\u7C7B
-doclet.subinterfaces=\u5B50\u63A5\u53E3
doclet.Modifier=\u9650\u5B9A\u7B26
doclet.Type=\u7C7B\u578B
doclet.Modifier_and_Type=\u4FEE\u9970\u7B26\u548C\u7C7B\u578B
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -187,8 +187,7 @@
main.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
main.unexpected.exception=\u4E88\u671F\u3057\u306A\u3044\u4F8B\u5916\u304C\u6355\u6349\u3055\u308C\u307E\u3057\u305F: {0}
doclet.internal.report.bug=Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(http://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002
-main.legacy_api=\u30D1\u30C3\u30B1\u30FC\u30B8com.sun.javadoc\u3001com.sun.tools.doclets\u304A\u3088\u3073\n\u305D\u308C\u3089\u306E\u5B9F\u88C5\u5185\u306E\u53E4\u3044Doclet\u304A\u3088\u3073Taglet API\u306F\u3001\n\u4ECA\u5F8C\u306EJDK\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059\u3002\u3053\u308C\u3089\u306E\n\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306Fjdk.javadoc.doclet\u306E\u65B0\u3057\u3044API\u306B\u3088\u3063\u3066\u7F6E\u304D\u63DB\u3048\u3089\u308C\u307E\u3057\u305F\u3002\n\u30E6\u30FC\u30B6\u30FC\u306B\u306F\u65B0\u3057\u3044API\u306B\u79FB\u884C\u3059\u308B\u3053\u3068\u3092\u5F37\u304F\u304A\u85A6\u3081\u3057\u307E\u3059\u3002\n
-
+main.not_a_doclet=\u30AF\u30E9\u30B9{0}\u306F\u6709\u52B9\u306A\u30C9\u30C3\u30AF\u30EC\u30C3\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\n\u6CE8\u610F: JDK 13\u304B\u3089\u3001com.sun.javadoc API\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u304F\u306A\u308A\u307E\u3057\u305F\u3002
javadoc.class_not_found=\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002
javadoc.error=\u30A8\u30E9\u30FC
javadoc.warning=\u8B66\u544A
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -187,8 +187,7 @@
main.internal.error=\u51FA\u73B0\u5185\u90E8\u9519\u8BEF
main.unexpected.exception=\u6355\u83B7\u5230\u610F\u5916\u7684\u5F02\u5E38\u9519\u8BEF: {0}
doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002
-main.legacy_api=\u5DF2\u8BA1\u5212\u5728\u672A\u6765\u7684 JDK \u53D1\u884C\u7248\u4E2D\u5220\u9664\u7A0B\u5E8F\u5305\ncom.sun.javadoc, com.sun.tools.doclets\n\u53CA\u5176\u5B9E\u73B0\u4E2D\u7684\u65E7 Doclet \u548C Taglet API\u3002\n\u8FD9\u4E9B\u7EC4\u4EF6\u5728 jdk.javadoc.doclet \u4E2D\u5DF2\u7531\u65B0 API \u53D6\u4EE3\u3002\n\u5F3A\u70C8\u5EFA\u8BAE\u7528\u6237\u8FC1\u79FB\u5230\u65B0 API\u3002\n
-
+main.not_a_doclet=\u7C7B {0} \u4E0D\u662F\u6709\u6548 doclet\u3002\n\u6CE8\u610F\uFF1A\u4ECE JDK 13 \u5F00\u59CB\uFF0C\u4E0D\u518D\u652F\u6301 com.sun.javadoc API\u3002
javadoc.class_not_found=\u627E\u4E0D\u5230\u7C7B{0}\u3002
javadoc.error=\u9519\u8BEF
javadoc.warning=\u8B66\u544A
--- a/src/jdk.javadoc/share/man/javadoc.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.javadoc/share/man/javadoc.1 Mon Jul 22 11:08:27 2019 +0530
@@ -447,13 +447,13 @@
See \f[I]Extra Options\f[R] in \f[B]javac\f[R] for the detailed
descriptions of using these options:
.IP \[bu] 2
-\f[CB]\-add\-exports\f[R]
+\f[CB]\-\-add\-exports\f[R]
.IP \[bu] 2
\f[CB]\-\-add\-reads\f[R]
.IP \[bu] 2
\f[CB]\-\-patch\-module\f[R]
.IP \[bu] 2
-\f[CB]\-\-Xmaxerrs\f[R]
+\f[CB]\-Xmaxerrs\f[R]
.IP \[bu] 2
\f[CB]\-Xmaxwarns\f[R]
.PP
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -68,9 +68,11 @@
main.opt.module_path=\ --module-path <path> \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+main.opt.multi_release=\ --multi-release <version> \u30DE\u30EB\u30C1\u30EA\u30EA\u30FC\u30B9JAR\u30D5\u30A1\u30A4\u30EB\u3067\u4F7F\u7528\u3059\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u6307\u5B9A\u3057\u307E\u3059
+
main.opt.constants=\ -constants final\u5B9A\u6570\u3092\u8868\u793A\u3059\u308B
-main.opt.sysinfo=\ -sysinfo \u51E6\u7406\u3057\u3066\u3044\u308B\u30AF\u30E9\u30B9\u306E\u30B7\u30B9\u30C6\u30E0\u60C5\u5831(\u30D1\u30B9\u3001\u30B5\u30A4\u30BA\u3001\u65E5\u4ED8\u3001MD5\u30CF\u30C3\u30B7\u30E5)\n \u3092\u8868\u793A\u3059\u308B
+main.opt.sysinfo=\ -sysinfo \u51E6\u7406\u3057\u3066\u3044\u308B\u30AF\u30E9\u30B9\u306E\u30B7\u30B9\u30C6\u30E0\u60C5\u5831(\u30D1\u30B9\u3001\u30B5\u30A4\u30BA\u3001\u65E5\u4ED8\u3001SHA-256\u30CF\u30C3\u30B7\u30E5)\n \u3092\u8868\u793A\u3057\u307E\u3059
main.opt.module=\ --module <module>\u3001-m <module> \u9006\u30A2\u30BB\u30F3\u30D6\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u3092\u542B\u3080\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3059\u308B
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -68,9 +68,11 @@
main.opt.module_path=\ --module-path <\u8DEF\u5F84> \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E
+main.opt.multi_release=\ --multi-release <version> \u6307\u5B9A\u8981\u5728\u591A\u53D1\u884C\u7248 JAR \u6587\u4EF6\u4E2D\u4F7F\u7528\u7684\u7248\u672C
+
main.opt.constants=\ -constants \u663E\u793A\u6700\u7EC8\u5E38\u91CF
-main.opt.sysinfo=\ -sysinfo \u663E\u793A\u6B63\u5728\u5904\u7406\u7684\u7C7B\u7684\n \u7CFB\u7EDF\u4FE1\u606F (\u8DEF\u5F84, \u5927\u5C0F, \u65E5\u671F, MD5 \u6563\u5217)
+main.opt.sysinfo=\ -sysinfo \u663E\u793A\u6B63\u5728\u5904\u7406\u7684\u7C7B\u7684\n \u7CFB\u7EDF\u4FE1\u606F\uFF08\u8DEF\u5F84\u3001\u5927\u5C0F\u3001\u65E5\u671F\u3001SHA-256 \u6563\u5217\uFF09
main.opt.module=\ --module <\u6A21\u5757>, -m <\u6A21\u5757> \u6307\u5B9A\u5305\u542B\u8981\u53CD\u6C47\u7F16\u7684\u7C7B\u7684\u6A21\u5757
--- a/src/jdk.jdeps/share/man/javap.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jdeps/share/man/javap.1 Mon Jul 22 11:08:27 2019 +0530
@@ -131,8 +131,8 @@
.RE
.TP
.B \f[CB]\-sysinfo\f[R]
-Shows system information (path, size, date, MD5 hash) of the class being
-processed.
+Shows system information (path, size, date, SHA\-256 hash) of the class
+being processed.
.RS
.RE
.TP
@@ -169,6 +169,11 @@
.RS
.RE
.TP
+.B \f[CB]\-\-multi\-release\f[R] \f[I]version\f[R]
+Specifies the version to select in multi\-release JAR files.
+.RS
+.RE
+.TP
.B \f[CB]\-J\f[R]\f[I]option\f[R]
Passes the specified option to the JVM.
For example:
--- a/src/jdk.jdeps/share/man/jdeps.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jdeps/share/man/jdeps.1 Mon Jul 22 11:08:27 2019 +0530
@@ -63,6 +63,11 @@
\f[CB]\-dotoutput\f[R] option).
.SH POSSIBLE OPTIONS
.TP
+.B \f[CB]\-?\f[R] or \f[CB]\-h\f[R] or \f[CB]\-\-help\f[R]
+Prints the help message.
+.RS
+.RE
+.TP
.B \f[CB]\-dotoutput\f[R] \f[I]dir\f[R] or \f[CB]\-\-dot\-output\f[R] \f[I]dir\f[R]
Specifies the destination directory for DOT file output.
If this option is specified, then the \f[CB]jdeps\f[R]command generates
@@ -296,7 +301,7 @@
.RS
.RE
.TP
-.B \f[CB]\-R\f[R] or \f[CB]\-recursive\f[R]
+.B \f[CB]\-R\f[R] or \f[CB]\-\-recursive\f[R]
Recursively traverses all run\-time dependences.
The \f[CB]\-R\f[R] option implies \f[CB]\-filter:none\f[R].
If \f[CB]\-p\f[R], \f[CB]\-e\f[R], or \f[CB]\-f\f[R] options are specified,
@@ -309,7 +314,7 @@
.RS
.RE
.TP
-.B \f[CB]\-I\f[R] or \f[CB]\-inverse\f[R]
+.B \f[CB]\-I\f[R] or \f[CB]\-\-inverse\f[R]
Analyzes the dependences per other given options and then finds all
artifacts that directly and indirectly depend on the matching nodes.
This is equivalent to the inverse of the compile\-time view analysis and
--- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_ja.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_ja.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,6 +107,7 @@
{"Current thread isnt suspended.", "\u73FE\u5728\u306E\u30B9\u30EC\u30C3\u30C9\u306F\u4E2D\u65AD\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
{"Current thread not set.", "\u73FE\u5728\u306E\u30B9\u30EC\u30C3\u30C9\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
{"dbgtrace flag value must be an integer:", "dbgtrace\u30D5\u30E9\u30B0\u5024\u306F\u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}"},
+ {"dbgtrace command value must be an integer:", "dbgtrace\u30B3\u30DE\u30F3\u30C9\u5024\u306F\u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}"},
{"Deferring.", "\u9045\u5EF6\u3057\u305F{0}\u3002\n\u30AF\u30E9\u30B9\u304C\u30ED\u30FC\u30C9\u3055\u308C\u305F\u5F8C\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002"},
{"End of stack.", "\u30B9\u30BF\u30C3\u30AF\u306E\u7D42\u308F\u308A\u3002"},
{"Error popping frame", "\u30D5\u30EC\u30FC\u30E0\u306E\u30DD\u30C3\u30D7\u4E2D\u306E\u30A8\u30E9\u30FC - {0}"},
@@ -119,12 +120,14 @@
{"Exception occurred caught", "\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0} (\u6355\u6349\u3055\u308C\u308B\u5834\u6240: {1})"},
{"Exception occurred uncaught", "\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0} (\u6355\u6349\u3055\u308C\u306A\u3044)"},
{"Exceptions caught:", "\u6B21\u306E\u4F8B\u5916\u304C\u767A\u751F\u3057\u305F\u3068\u304D\u306B\u30D6\u30EC\u30FC\u30AF:"},
+ {"Expected at, in, or an integer <thread_id>:", "\"at\"\u3001\"in\"\u307E\u305F\u306F\u6574\u6570\u306E<thread_id>\u304C\u5FC5\u8981\u3067\u3059: {0}"},
{"expr is null", "{0} = null"},
{"expr is value", "{0} = {1}"},
{"expr is value <collected>", " {0} = {1} <collected>"},
{"Expression cannot be void", "\u5F0F\u306Fvoid\u578B\u306B\u3067\u304D\u307E\u305B\u3093"},
{"Expression must evaluate to an object", "\u5F0F\u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3068\u3057\u3066\u8A55\u4FA1\u3055\u308C\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
{"extends:", "\u62E1\u5F35\u3057\u307E\u3059: {0}"},
+ {"Extra tokens after breakpoint location", "\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u306E\u5834\u6240\u306E\u5F8C\u306E\u8FFD\u52A0\u30C8\u30FC\u30AF\u30F3"},
{"Failed reading output", "\u5B50\u306Ejava\u30A4\u30F3\u30BF\u30FC\u30D7\u30EA\u30BF\u306E\u51FA\u529B\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002"},
{"Fatal error", "\u81F4\u547D\u7684\u30A8\u30E9\u30FC:"},
{"Field access encountered before after", "\u30D5\u30A3\u30FC\u30EB\u30C9({0})\u306F{1}\u3067\u3001{2}\u306B\u306A\u308A\u307E\u3059: "},
@@ -153,11 +156,14 @@
{"Invalid connect type", "\u63A5\u7D9A\u578B\u304C\u7121\u52B9\u3067\u3059"},
{"Invalid consecutive invocations", "\u9023\u7D9A\u547C\u51FA\u3057\u304C\u7121\u52B9\u3067\u3059"},
{"Invalid exception object", "\u4F8B\u5916\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u304C\u7121\u52B9\u3067\u3059"},
- {"Invalid method specification:", "\u7121\u52B9\u306A\u30E1\u30BD\u30C3\u30C9\u6307\u5B9A: {0}"},
+ {"Invalid line number specified", "\u7121\u52B9\u306A\u884C\u756A\u53F7\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
+ {"Invalid <method_name> specification:", "\u7121\u52B9\u306A<method_name>\u6307\u5B9A: {0}"},
{"Invalid option on class command", "class\u30B3\u30DE\u30F3\u30C9\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u7121\u52B9\u3067\u3059"},
{"invalid option", "\u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}"},
{"Invalid thread status.", "\u30B9\u30EC\u30C3\u30C9\u72B6\u614B\u304C\u7121\u52B9\u3067\u3059\u3002"},
+ {"Invalid <thread_id>:", "\u7121\u52B9\u306A<thread_id>: {0}"},
{"Invalid transport name:", "\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u540D\u304C\u7121\u52B9\u3067\u3059: {0}"},
+ {"Invalid <class>.<method_name> specification", "\u7121\u52B9\u306A<class>.<method_name>\u6307\u5B9A"},
{"I/O exception occurred:", "\u5165\u51FA\u529B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}"},
{"is an ambiguous method name in", "\"{0}\"\u306F\"{1}\"\u306E\u3042\u3044\u307E\u3044\u306A\u30E1\u30BD\u30C3\u30C9\u540D\u3067\u3059"},
{"is an invalid line number for", "{0,number,integer}\u306F{1}\u306E\u7121\u52B9\u306A\u884C\u756A\u53F7\u3067\u3059"},
@@ -190,6 +196,7 @@
{"Method exitedValue:", "\u30E1\u30BD\u30C3\u30C9\u304C\u7D42\u4E86\u3057\u307E\u3057\u305F: \u623B\u308A\u5024= {0}, "},
{"Method is overloaded; specify arguments", "\u30E1\u30BD\u30C3\u30C9{0}\u304C\u30AA\u30FC\u30D0\u30FC\u30ED\u30FC\u30C9\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u5F15\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"},
{"minus version", "\u3053\u308C\u306F{0}\u30D0\u30FC\u30B8\u30E7\u30F3{1,number,integer}.{2,number,integer} (Java SE\u30D0\u30FC\u30B8\u30E7\u30F3{3})\u3067\u3059"},
+ {"Missing at or in", "\"at\"\u307E\u305F\u306F\"in\"\u304C\u3042\u308A\u307E\u305B\u3093"},
{"Monitor information for thread", "\u30B9\u30EC\u30C3\u30C9{0}\u306E\u60C5\u5831\u306E\u30E2\u30CB\u30BF\u30FC:"},
{"Monitor information for expr", "{0} ({1})\u306E\u60C5\u5831\u306E\u30E2\u30CB\u30BF\u30FC:"},
{"More than one class named", "\u540D\u524D''{0}''\u306E\u30AF\u30E9\u30B9\u304C\u8907\u6570\u3042\u308A\u307E\u3059"},
@@ -234,13 +241,16 @@
{"Not owned", " \u6240\u6709\u3055\u308C\u3066\u3044\u307E\u305B\u3093"},
{"Not waiting for a monitor", " \u30E2\u30CB\u30BF\u30FC\u3092\u5F85\u6A5F\u3057\u3066\u3044\u307E\u305B\u3093"},
{"Nothing suspended.", "\u4F55\u3082\u4E2D\u65AD\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"object description and hex id", "({0}){1}"},
+ {"object description and id", "({0}){1}"},
{"Operation is not supported on the target VM", "\u64CD\u4F5C\u306F\u30BF\u30FC\u30B2\u30C3\u30C8VM\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093"},
{"operation not yet supported", "\u307E\u3060\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u64CD\u4F5C"},
{"Owned by:", " \u6240\u6709\u8005: {0}\u3001\u30A8\u30F3\u30C8\u30EA\u6570: {1,number,integer}"},
{"Owned monitor:", " \u6240\u6709\u3055\u308C\u3066\u3044\u308B\u30E2\u30CB\u30BF\u30FC: {0}"},
{"Parse exception:", "\u4F8B\u5916\u306E\u89E3\u6790: {0}"},
- {"printbreakpointcommandusage", "\u4F7F\u7528\u65B9\u6CD5: {0} <class>:<line_number>\u307E\u305F\u306F\n {1} <class>.<method_name>[(argument_type,...)]"},
+ {"printclearcommandusage", "\u4F7F\u7528\u65B9\u6CD5 clear <class>:<line_number>\u307E\u305F\u306F\n clear <class>.<method_name>[(argument_type,...)]"},
+ {"printstopcommandusage",
+ "\u4F7F\u7528\u65B9\u6CD5: stop [go|thread] [<thread_id>] <at|in> <location>\n \"go\"\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u505C\u6B62\u5F8C\u3059\u3050\u306B\u518D\u958B\u3057\u307E\u3059\n \"thread\"\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u505C\u6B62\u3057\u305F\u30B9\u30EC\u30C3\u30C9\u306E\u307F\u4E2D\u65AD\u3057\u307E\u3059\n \"go\"\u3082\"thread\"\u3082\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u306F\u3001\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3057\u307E\u3059\n \u6574\u6570\u306E<thread_id>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u6307\u5B9A\u3055\u308C\u305F\u30B9\u30EC\u30C3\u30C9\u3067\u306E\u307F\u505C\u6B62\u3057\u307E\u3059\n \"at\"\u3068\"in\"\u306F\u540C\u3058\u610F\u5473\u3092\u6301\u3061\u307E\u3059\n <location>\u306F\u884C\u756A\u53F7\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u306B\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059:\n <class_id>:<line_number>\n <class_id>.<method>[(argument_type,...)]"
+ },
{"Removed:", "{0}\u306F\u524A\u9664\u3055\u308C\u307E\u3057\u305F"},
{"Requested stack frame is no longer active:", "\u30EA\u30AF\u30A8\u30B9\u30C8\u3055\u308C\u305F\u30B9\u30BF\u30C3\u30AF\u30FB\u30D5\u30EC\u30FC\u30E0\u306F\u73FE\u5728\u30A2\u30AF\u30C6\u30A3\u30D6\u3067\u306F\u3042\u308A\u307E\u305B\u3093: {0,number,integer}"},
{"run <args> command is valid only with launched VMs", "'run <args>'\u30B3\u30DE\u30F3\u30C9\u306F\u8D77\u52D5\u6E08\u306EVM\u3067\u306E\u307F\u6709\u52B9\u3067\u3059"},
@@ -289,6 +299,8 @@
{"Thread not suspended", "\u30B9\u30EC\u30C3\u30C9\u306F\u4E2D\u65AD\u3057\u3066\u3044\u307E\u305B\u3093"},
{"thread group number description name", "{0,number,integer}. {1} {2}"},
{"Threadgroup name not specified.", "\u30B9\u30EC\u30C3\u30C9\u30B0\u30EB\u30FC\u30D7\u540D\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
+ {"<thread_id> option not valid until the VM is started with the run command",
+ "<thread_id>\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u3001VM\u304Crun\u30B3\u30DE\u30F3\u30C9\u3067\u958B\u59CB\u3055\u308C\u308B\u307E\u3067\u7121\u52B9\u3067\u3059"},
{"Threads must be suspended", "\u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
{"trace method exit in effect for", "{0}\u306B\u5BFE\u3057\u3066\u6709\u52B9\u306A\u30E1\u30BD\u30C3\u30C9\u7D42\u4E86\u306E\u30C8\u30EC\u30FC\u30B9"},
{"trace method exits in effect", "\u6709\u52B9\u306A\u30E1\u30BD\u30C3\u30C9\u7D42\u4E86\u306E\u30C8\u30EC\u30FC\u30B9"},
@@ -315,7 +327,6 @@
{"Usage: unmonitor <monitor#>", "\u4F7F\u7528\u65B9\u6CD5: unmonitor <monitor#>"},
{"Usage: up [n frames]", "\u4F7F\u7528\u65B9\u6CD5: up [n frames]"},
{"Use java minus X to see", "\u4F7F\u7528\u53EF\u80FD\u306A\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3059\u308B\u306B\u306F'java -X'\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044"},
- {"Use stop at to set a breakpoint at a line number", "\u884C\u756A\u53F7\u306B\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u5B9A\u3059\u308B\u306B\u306F'stop at'\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044"},
{"VM already running. use cont to continue after events.", "VM\u306F\u3059\u3067\u306B\u5B9F\u884C\u4E2D\u3067\u3059\u3002\u30A4\u30D9\u30F3\u30C8\u5F8C\u306B\u7D9A\u884C\u3059\u308B\u306B\u306F'cont'\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
{"VM Started:", "VM\u304C\u958B\u59CB\u3055\u308C\u307E\u3057\u305F: "},
{"vmstartexception", "VM\u304C\u4F8B\u5916\u3092\u958B\u59CB\u3057\u307E\u3057\u305F: {0}"},
@@ -324,7 +335,7 @@
{"watch accesses of", "{0}.{1}\u306E\u30A2\u30AF\u30BB\u30B9\u3092\u30A6\u30A9\u30C3\u30C1"},
{"watch modification of", "{0}.{1}\u306E\u5909\u66F4\u306E\u30A6\u30A9\u30C3\u30C1"},
{"zz help text",
- "** \u30B3\u30DE\u30F3\u30C9\u30FB\u30EA\u30B9\u30C8 **\nconnectors -- \u3053\u306EVM\u5185\u306E\u4F7F\u7528\u53EF\u80FD\u306A\u30B3\u30CD\u30AF\u30BF\u3068\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\n\nrun [class [args]] -- \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u306E\u5B9F\u884C\u3092\u958B\u59CB\u3057\u307E\u3059\n\nthreads [threadgroup] -- \u30B9\u30EC\u30C3\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nthread <thread id> -- \u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30B9\u30EC\u30C3\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\nsuspend [thread id(s)] -- \u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8: \u3059\u3079\u3066)\nresume [thread id(s)] -- \u30B9\u30EC\u30C3\u30C9\u3092\u518D\u958B\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8: \u3059\u3079\u3066)\nwhere [<thread id> | all] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u30C0\u30F3\u30D7\u3057\u307E\u3059\nwherei [<thread id> | all]-- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092pc\u60C5\u5831\u3068\u3068\u3082\u306B\u30C0\u30F3\u30D7\u3057\u307E\u3059\nup [n frames] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u4E0A\u306B\u79FB\u52D5\u3057\u307E\u3059\ndown [n frames] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u4E0B\u306B\u79FB\u52D5\u3057\u307E\u3059\nkill <thread id> <expr> -- \u6307\u5B9A\u3055\u308C\u305F\u4F8B\u5916\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u30B9\u30EC\u30C3\u30C9\u3092\u5F37\u5236\u7D42\u4E86\u3057\u307E\u3059\ninterrupt <thread id> -- \u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3057\u307E\u3059\n\nprint <expr> -- \u5F0F\u306E\u5024\u3092\u51FA\u529B\u3057\u307E\u3059\ndump <expr> -- \u3059\u3079\u3066\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\neval <expr> -- \u5F0F\u3092\u8A55\u4FA1\u3057\u307E\u3059(print\u3068\u540C\u3058)\nset <lvalue> = <expr> -- \u65B0\u3057\u3044\u5024\u3092\u30D5\u30A3\u30FC\u30EB\u30C9/\u5909\u6570/\u914D\u5217\u8981\u7D20\u306B\u4EE3\u5165\u3057\u307E\u3059\nlocals -- \u73FE\u5728\u306E\u30B9\u30BF\u30C3\u30AF\u30FB\u30D5\u30EC\u30FC\u30E0\u5185\u306E\u3059\u3079\u3066\u306E\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u3092\u51FA\u529B\u3057\u307E\u3059\n\nclasses -- \u73FE\u5728\u65E2\u77E5\u306E\u30AF\u30E9\u30B9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nclass <class id> -- \u6307\u5B9A\u3057\u305F\u30AF\u30E9\u30B9\u306E\u8A73\u7D30\u3092\u8868\u793A\u3057\u307E\u3059\nmethods <class id> -- \u30AF\u30E9\u30B9\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nfields <class id> -- \u30AF\u30E9\u30B9\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\n\nthreadgroups -- \u30B9\u30EC\u30C3\u30C9\u30B0\u30EB\u30FC\u30D7\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nthreadgroup <name> -- \u73FE\u5728\u306E\u30B9\u30EC\u30C3\u30C9\u30B0\u30EB\u30FC\u30D7\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n\nstop in <class id>.<method>[(argument_type,...)]\n -- \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30E1\u30BD\u30C3\u30C9\u5185\u306B\u8A2D\u5B9A\u3057\u307E\u3059\nstop at <class id>:<line> -- \u884C\u306B\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\nclear <class id>.<method>[(argument_type,...)]\n -- \u30E1\u30BD\u30C3\u30C9\u5185\u306E\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3059\nclear <class id>:<line> -- \u884C\u306E\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3059\nclear -- \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\ncatch [uncaught|caught|all] <class id>|<class pattern>\n -- \u6307\u5B9A\u3055\u308C\u305F\u4F8B\u5916\u304C\u767A\u751F\u3057\u305F\u3068\u304D\u306B\u30D6\u30EC\u30FC\u30AF\u3057\u307E\u3059\nignore [uncaught|caught|all] <class id>|<class pattern>\n -- \u6307\u5B9A\u3055\u308C\u305F\u4F8B\u5916\u306E'catch'\u3092\u53D6\u308A\u6D88\u3057\u307E\u3059\nwatch [access|all] <class id>.<field name>\n -- \u30D5\u30A3\u30FC\u30EB\u30C9\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u307E\u305F\u306F\u5909\u66F4\u3092\u30A6\u30A9\u30C3\u30C1\u3057\u307E\u3059\nunwatch [access|all] <class id>.<field name>\n -- \u30D5\u30A3\u30FC\u30EB\u30C9\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u307E\u305F\u306F\u5909\u66F4\u306E\u30A6\u30A9\u30C3\u30C1\u3092\u4E2D\u6B62\u3057\u307E\u3059\ntrace [go] methods [thread]\n -- \u30E1\u30BD\u30C3\u30C9\u306E\u5165\u308A\u53E3\u3068\u51FA\u53E3\u3092\u30C8\u30EC\u30FC\u30B9\u3057\u307E\u3059\u3002\n -- 'go'\u304C\u6307\u5B9A\u3055\u308C\u308B\u307E\u3067\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u306F\u4E2D\u65AD\u3057\u307E\u3059\ntrace [go] method exit | exits [thread]\n -- \u73FE\u5728\u306E\u30E1\u30BD\u30C3\u30C9\u306E\u51FA\u53E3\u307E\u305F\u306F\u3059\u3079\u3066\u306E\u30E1\u30BD\u30C3\u30C9\u306E\u51FA\u53E3\u3092\u30C8\u30EC\u30FC\u30B9\u3057\u307E\u3059\n -- 'go'\u304C\u6307\u5B9A\u3055\u308C\u308B\u307E\u3067\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u306F\u4E2D\u65AD\u3057\u307E\u3059\nuntrace [methods] -- \u30E1\u30BD\u30C3\u30C9\u306E\u958B\u59CB\u307E\u305F\u306F\u7D42\u4E86\u306E\u30C8\u30EC\u30FC\u30B9\u3092\u505C\u6B62\u3057\u307E\u3059\nstep -- \u73FE\u5728\u306E\u884C\u3092\u5B9F\u884C\u3057\u307E\u3059\nstep up -- \u73FE\u5728\u306E\u30E1\u30BD\u30C3\u30C9\u304C\u30E1\u30BD\u30C3\u30C9\u306E\u547C\u51FA\u3057\u5143\u306B\u623B\u308B\u307E\u3067\u5B9F\u884C\u3057\u307E\u3059\nstepi -- \u73FE\u5728\u306E\u547D\u4EE4\u3092\u5B9F\u884C\u3057\u307E\u3059\nnext -- 1\u884C\u3092\u30B9\u30C6\u30C3\u30D7\u5B9F\u884C\u3057\u307E\u3059(\u547C\u51FA\u3057\u3092\u30B9\u30C6\u30C3\u30D7\u30AA\u30FC\u30D0\u30FC)\ncont -- \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u304B\u3089\u5B9F\u884C\u3092\u7D9A\u884C\u3057\u307E\u3059\n\nlist [line number|method] -- \u30BD\u30FC\u30B9\u30FB\u30B3\u30FC\u30C9\u3092\u51FA\u529B\u3057\u307E\u3059\nuse (or sourcepath) [source file path]\n -- \u30BD\u30FC\u30B9\u30FB\u30D1\u30B9\u3092\u8868\u793A\u307E\u305F\u306F\u5909\u66F4\u3057\u307E\u3059\nexclude [<class pattern>, ... | \"none\"]\n -- \u6307\u5B9A\u3057\u305F\u30AF\u30E9\u30B9\u306E\u30B9\u30C6\u30C3\u30D7\u3084\u30E1\u30BD\u30C3\u30C9\u30FB\u30A4\u30D9\u30F3\u30C8\u3092\u5831\u544A\u3057\u307E\u305B\u3093\nclasspath -- \u30BF\u30FC\u30B2\u30C3\u30C8VM\u304B\u3089\u30AF\u30E9\u30B9\u30D1\u30B9\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\n\nmonitor <command> -- \u30D7\u30ED\u30B0\u30E9\u30E0\u304C\u505C\u6B62\u3059\u308B\u305F\u3073\u306B\u30B3\u30DE\u30F3\u30C9\u3092\u5B9F\u884C\u3057\u307E\u3059\nmonitor -- \u30E2\u30CB\u30BF\u30FC\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nunmonitor <monitor#> -- \u30E2\u30CB\u30BF\u30FC\u3092\u524A\u9664\u3057\u307E\u3059\nread <filename> -- \u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u3063\u3066\u5B9F\u884C\u3057\u307E\u3059\n\nlock <expr> -- \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30ED\u30C3\u30AF\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\nthreadlocks [thread id] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30ED\u30C3\u30AF\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\n\npop -- \u73FE\u5728\u306E\u30D5\u30EC\u30FC\u30E0\u307E\u3067\u306E\u3059\u3079\u3066\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u30DD\u30C3\u30D7\u3057\u307E\u3059\nreenter -- pop\u3068\u540C\u3058\u3067\u3059\u304C\u3001\u73FE\u5728\u306E\u30D5\u30EC\u30FC\u30E0\u304C\u518D\u5165\u529B\u3055\u308C\u307E\u3059\nredefine <class id> <class file name>\n -- \u30AF\u30E9\u30B9\u306E\u30B3\u30FC\u30C9\u3092\u518D\u5B9A\u7FA9\u3057\u307E\u3059\n\ndisablegc <expr> -- \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u6291\u5236\u3057\u307E\u3059\nenablegc <expr> -- \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u8A31\u53EF\u3057\u307E\u3059\n\n!! -- \u6700\u5F8C\u306E\u30B3\u30DE\u30F3\u30C9\u3092\u7E70\u308A\u8FD4\u3057\u307E\u3059\n<n> <command> -- \u30B3\u30DE\u30F3\u30C9\u3092n\u56DE\u7E70\u308A\u8FD4\u3057\u307E\u3059\n# <command> -- \u7834\u68C4\u3057\u307E\u3059(\u64CD\u4F5C\u306A\u3057)\nhelp (\u307E\u305F\u306F?) -- \u30B3\u30DE\u30F3\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nversion -- \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\nexit (\u307E\u305F\u306Fquit) -- \u30C7\u30D0\u30C3\u30AC\u3092\u7D42\u4E86\u3057\u307E\u3059\n\n<class id>: \u30D1\u30C3\u30B1\u30FC\u30B8\u4FEE\u98FE\u5B50\u3092\u542B\u3080\u5B8C\u5168\u30AF\u30E9\u30B9\u540D\n<class pattern>: \u5148\u982D\u307E\u305F\u306F\u672B\u5C3E\u306E\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9('*')\u3092\u542B\u3080\u30AF\u30E9\u30B9\u540D\n<thread id>: 'threads'\u30B3\u30DE\u30F3\u30C9\u3067\u5831\u544A\u3055\u308C\u308B\u30B9\u30EC\u30C3\u30C9\u756A\u53F7\n<expr>: Java(TM)\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u306E\u5F0F\u3002\n\u307B\u3068\u3093\u3069\u306E\u4E00\u822C\u7684\u306A\u69CB\u6587\u304C\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\u3002\n\n\u8D77\u52D5\u30B3\u30DE\u30F3\u30C9\u306F\u3001\"jdb.ini\"\u307E\u305F\u306F\".jdbrc\"\u306B\u914D\u7F6E\u3067\u304D\u307E\u3059\n(user.home\u307E\u305F\u306Fuser.dir\u5185)"},
+ "** \u30B3\u30DE\u30F3\u30C9\u30FB\u30EA\u30B9\u30C8 **\nconnectors -- \u3053\u306EVM\u5185\u306E\u4F7F\u7528\u53EF\u80FD\u306A\u30B3\u30CD\u30AF\u30BF\u3068\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\n\nrun [class [args]] -- \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u306E\u5B9F\u884C\u3092\u958B\u59CB\u3057\u307E\u3059\n\nthreads [threadgroup] -- \u30B9\u30EC\u30C3\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nthread <thread id> -- \u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30B9\u30EC\u30C3\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\nsuspend [thread id(s)] -- \u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8: \u3059\u3079\u3066)\nresume [thread id(s)] -- \u30B9\u30EC\u30C3\u30C9\u3092\u518D\u958B\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8: \u3059\u3079\u3066)\nwhere [<thread id> | all] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u30C0\u30F3\u30D7\u3057\u307E\u3059\nwherei [<thread id> | all]-- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092pc\u60C5\u5831\u3068\u3068\u3082\u306B\u30C0\u30F3\u30D7\u3057\u307E\u3059\nup [n frames] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u4E0A\u306B\u79FB\u52D5\u3057\u307E\u3059\ndown [n frames] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u4E0B\u306B\u79FB\u52D5\u3057\u307E\u3059\nkill <thread id> <expr> -- \u6307\u5B9A\u3055\u308C\u305F\u4F8B\u5916\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u30B9\u30EC\u30C3\u30C9\u3092\u5F37\u5236\u7D42\u4E86\u3057\u307E\u3059\ninterrupt <thread id> -- \u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3057\u307E\u3059\n\nprint <expr> -- \u5F0F\u306E\u5024\u3092\u51FA\u529B\u3057\u307E\u3059\ndump <expr> -- \u3059\u3079\u3066\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\neval <expr> -- \u5F0F\u3092\u8A55\u4FA1\u3057\u307E\u3059(print\u3068\u540C\u3058)\nset <lvalue> = <expr> -- \u65B0\u3057\u3044\u5024\u3092\u30D5\u30A3\u30FC\u30EB\u30C9/\u5909\u6570/\u914D\u5217\u8981\u7D20\u306B\u4EE3\u5165\u3057\u307E\u3059\nlocals -- \u73FE\u5728\u306E\u30B9\u30BF\u30C3\u30AF\u30FB\u30D5\u30EC\u30FC\u30E0\u5185\u306E\u3059\u3079\u3066\u306E\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u3092\u51FA\u529B\u3057\u307E\u3059\n\nclasses -- \u73FE\u5728\u65E2\u77E5\u306E\u30AF\u30E9\u30B9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nclass <class id> -- \u6307\u5B9A\u3057\u305F\u30AF\u30E9\u30B9\u306E\u8A73\u7D30\u3092\u8868\u793A\u3057\u307E\u3059\nmethods <class id> -- \u30AF\u30E9\u30B9\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nfields <class id> -- \u30AF\u30E9\u30B9\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\n\nthreadgroups -- \u30B9\u30EC\u30C3\u30C9\u30B0\u30EB\u30FC\u30D7\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nthreadgroup <name> -- \u73FE\u5728\u306E\u30B9\u30EC\u30C3\u30C9\u30B0\u30EB\u30FC\u30D7\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n\nstop [go|thread] [<thread_id>] <at|in> <location>\n -- \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n -- \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u306F\u3001\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u306E\u73FE\u5728\u306E\u30EA\u30B9\u30C8\u304C\u51FA\u529B\u3055\u308C\u307E\u3059\n -- \"go\"\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u505C\u6B62\u5F8C\u3059\u3050\u306B\u518D\u958B\u3057\u307E\u3059\n -- \"thread\"\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u505C\u6B62\u3057\u305F\u30B9\u30EC\u30C3\u30C9\u306E\u307F\u4E2D\u65AD\u3057\u307E\u3059\n -- \"go\"\u3082\"thread\"\u3082\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u306F\u3001\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u3092\u4E2D\u65AD\u3057\u307E\u3059\n -- \u6574\u6570\u306E<thread_id>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u6307\u5B9A\u3055\u308C\u305F\u30B9\u30EC\u30C3\u30C9\u3067\u306E\u307F\u505C\u6B62\u3057\u307E\u3059\n -- \"at\"\u3068\"in\"\u306F\u540C\u3058\u610F\u5473\u3092\u6301\u3061\u307E\u3059\n -- <location>\u306F\u884C\u756A\u53F7\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u306B\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059:\n -- <class_id>:<line_number>\n -- <class_id>.<method>[(argument_type,...)]\nclear <class id>.<method>[(argument_type,...)]\n -- \u30E1\u30BD\u30C3\u30C9\u5185\u306E\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3059\nclear <class id>:<line> -- \u884C\u306E\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3059\nclear -- \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\ncatch [uncaught|caught|all] <class id>|<class pattern>\n -- \u6307\u5B9A\u3055\u308C\u305F\u4F8B\u5916\u304C\u767A\u751F\u3057\u305F\u3068\u304D\u306B\u30D6\u30EC\u30FC\u30AF\u3057\u307E\u3059\nignore [uncaught|caught|all] <class id>|<class pattern>\n -- \u6307\u5B9A\u3055\u308C\u305F\u4F8B\u5916\u306E'catch'\u3092\u53D6\u308A\u6D88\u3057\u307E\u3059\nwatch [access|all] <class id>.<field name>\n -- \u30D5\u30A3\u30FC\u30EB\u30C9\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u307E\u305F\u306F\u5909\u66F4\u3092\u30A6\u30A9\u30C3\u30C1\u3057\u307E\u3059\nunwatch [access|all] <class id>.<field name>\n -- \u30D5\u30A3\u30FC\u30EB\u30C9\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u307E\u305F\u306F\u5909\u66F4\u306E\u30A6\u30A9\u30C3\u30C1\u3092\u4E2D\u6B62\u3057\u307E\u3059\ntrace [go] methods [thread]\n -- \u30E1\u30BD\u30C3\u30C9\u306E\u5165\u308A\u53E3\u3068\u51FA\u53E3\u3092\u30C8\u30EC\u30FC\u30B9\u3057\u307E\u3059\u3002\n -- 'go'\u304C\u6307\u5B9A\u3055\u308C\u308B\u307E\u3067\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u306F\u4E2D\u65AD\u3057\u307E\u3059\ntrace [go] method exit | exits [thread]\n -- \u73FE\u5728\u306E\u30E1\u30BD\u30C3\u30C9\u306E\u51FA\u53E3\u307E\u305F\u306F\u3059\u3079\u3066\u306E\u30E1\u30BD\u30C3\u30C9\u306E\u51FA\u53E3\u3092\u30C8\u30EC\u30FC\u30B9\u3057\u307E\u3059\n -- 'go'\u304C\u6307\u5B9A\u3055\u308C\u308B\u307E\u3067\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u306F\u4E2D\u65AD\u3057\u307E\u3059\nuntrace [methods] -- \u30E1\u30BD\u30C3\u30C9\u306E\u958B\u59CB\u307E\u305F\u306F\u7D42\u4E86\u306E\u30C8\u30EC\u30FC\u30B9\u3092\u505C\u6B62\u3057\u307E\u3059\nstep -- \u73FE\u5728\u306E\u884C\u3092\u5B9F\u884C\u3057\u307E\u3059\nstep up -- \u73FE\u5728\u306E\u30E1\u30BD\u30C3\u30C9\u304C\u30E1\u30BD\u30C3\u30C9\u306E\u547C\u51FA\u3057\u5143\u306B\u623B\u308B\u307E\u3067\u5B9F\u884C\u3057\u307E\u3059\nstepi -- \u73FE\u5728\u306E\u547D\u4EE4\u3092\u5B9F\u884C\u3057\u307E\u3059\nnext -- 1\u884C\u3092\u30B9\u30C6\u30C3\u30D7\u5B9F\u884C\u3057\u307E\u3059(\u547C\u51FA\u3057\u3092\u30B9\u30C6\u30C3\u30D7\u30AA\u30FC\u30D0\u30FC)\ncont -- \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u304B\u3089\u5B9F\u884C\u3092\u7D9A\u884C\u3057\u307E\u3059\n\nlist [line number|method] -- \u30BD\u30FC\u30B9\u30FB\u30B3\u30FC\u30C9\u3092\u51FA\u529B\u3057\u307E\u3059\nuse (or sourcepath) [source file path]\n -- \u30BD\u30FC\u30B9\u30FB\u30D1\u30B9\u3092\u8868\u793A\u307E\u305F\u306F\u5909\u66F4\u3057\u307E\u3059\nexclude [<class pattern>, ... | \"none\"]\n -- \u6307\u5B9A\u3057\u305F\u30AF\u30E9\u30B9\u306E\u30B9\u30C6\u30C3\u30D7\u3084\u30E1\u30BD\u30C3\u30C9\u30FB\u30A4\u30D9\u30F3\u30C8\u3092\u5831\u544A\u3057\u307E\u305B\u3093\nclasspath -- \u30BF\u30FC\u30B2\u30C3\u30C8VM\u304B\u3089\u30AF\u30E9\u30B9\u30D1\u30B9\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\n\nmonitor <command> -- \u30D7\u30ED\u30B0\u30E9\u30E0\u304C\u505C\u6B62\u3059\u308B\u305F\u3073\u306B\u30B3\u30DE\u30F3\u30C9\u3092\u5B9F\u884C\u3057\u307E\u3059\nmonitor -- \u30E2\u30CB\u30BF\u30FC\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\nunmonitor <monitor#> -- \u30E2\u30CB\u30BF\u30FC\u3092\u524A\u9664\u3057\u307E\u3059\nread <filename> -- \u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u3063\u3066\u5B9F\u884C\u3057\u307E\u3059\n\nlock <expr> -- \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30ED\u30C3\u30AF\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\nthreadlocks [thread id] -- \u30B9\u30EC\u30C3\u30C9\u306E\u30ED\u30C3\u30AF\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\n\npop -- \u73FE\u5728\u306E\u30D5\u30EC\u30FC\u30E0\u307E\u3067\u306E\u3059\u3079\u3066\u306E\u30B9\u30BF\u30C3\u30AF\u3092\u30DD\u30C3\u30D7\u3057\u307E\u3059\nreenter -- pop\u3068\u540C\u3058\u3067\u3059\u304C\u3001\u73FE\u5728\u306E\u30D5\u30EC\u30FC\u30E0\u304C\u518D\u5165\u529B\u3055\u308C\u307E\u3059\nredefine <class id> <class file name>\n -- \u30AF\u30E9\u30B9\u306E\u30B3\u30FC\u30C9\u3092\u518D\u5B9A\u7FA9\u3057\u307E\u3059\n\ndisablegc <expr> -- \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u6291\u5236\u3057\u307E\u3059\nenablegc <expr> -- \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u8A31\u53EF\u3057\u307E\u3059\n\n!! -- \u6700\u5F8C\u306E\u30B3\u30DE\u30F3\u30C9\u3092\u7E70\u308A\u8FD4\u3057\u307E\u3059\n<n> <command> -- \u30B3\u30DE\u30F3\u30C9\u3092n\u56DE\u7E70\u308A\u8FD4\u3057\u307E\u3059\n# <command> -- \u7834\u68C4\u3057\u307E\u3059(\u64CD\u4F5C\u306A\u3057)\nhelp (\u307E\u305F\u306F?) -- \u30B3\u30DE\u30F3\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059\ndbgtrace [flag] -- dbgtrace\u30B3\u30DE\u30F3\u30C9\u30FB\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u540C\u3058\u3067\u3059\nversion -- \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\nexit (\u307E\u305F\u306Fquit) -- \u30C7\u30D0\u30C3\u30AC\u3092\u7D42\u4E86\u3057\u307E\u3059\n\n<class id>: \u30D1\u30C3\u30B1\u30FC\u30B8\u4FEE\u98FE\u5B50\u3092\u542B\u3080\u5B8C\u5168\u30AF\u30E9\u30B9\u540D\n<class pattern>: \u5148\u982D\u307E\u305F\u306F\u672B\u5C3E\u306E\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9('*')\u3092\u542B\u3080\u30AF\u30E9\u30B9\u540D\n<thread id>: 'threads'\u30B3\u30DE\u30F3\u30C9\u3067\u5831\u544A\u3055\u308C\u308B\u30B9\u30EC\u30C3\u30C9\u756A\u53F7\n<expr>: Java(TM)\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u306E\u5F0F\u3002\n\u307B\u3068\u3093\u3069\u306E\u4E00\u822C\u7684\u306A\u69CB\u6587\u304C\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\u3002\n\n\u8D77\u52D5\u30B3\u30DE\u30F3\u30C9\u306F\u3001\"jdb.ini\"\u307E\u305F\u306F\".jdbrc\"\u306B\u914D\u7F6E\u3067\u304D\u307E\u3059\n(user.home\u307E\u305F\u306Fuser.dir\u5185)"},
{"zz usage text",
"\u4F7F\u7528\u65B9\u6CD5: {0} <options> <class> <arguments>\n\n\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n -? -h --help -help \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n -sourcepath <directories separated by \"{1}\">\n \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n -attach <address>\n \u6A19\u6E96\u30B3\u30CD\u30AF\u30BF\u3092\u4F7F\u7528\u3057\u3066\u3001\u6307\u5B9A\u3055\u308C\u305F\u30A2\u30C9\u30EC\u30B9\u3067\u5B9F\u884C\u4E2D\u306EVM\u306B\u63A5\u7D9A\u3059\u308B\n -listen <address>\n \u6A19\u6E96\u30B3\u30CD\u30AF\u30BF\u3092\u4F7F\u7528\u3057\u3066\u3001\u6307\u5B9A\u3055\u308C\u305F\u30A2\u30C9\u30EC\u30B9\u3067\u5B9F\u884C\u4E2D\u306EVM\u306E\u63A5\u7D9A\u3092\u5F85\u6A5F\u3059\u308B\n -listenany\n \u6A19\u6E96\u30B3\u30CD\u30AF\u30BF\u3092\u4F7F\u7528\u3057\u3066\u3001\u4F7F\u7528\u53EF\u80FD\u306A\u4EFB\u610F\u306E\u30A2\u30C9\u30EC\u30B9\u3067\u5B9F\u884C\u4E2D\u306EVM\u306E\u63A5\u7D9A\u3092\u5F85\u6A5F\u3059\u308B\n -launch\n ''run''\u30B3\u30DE\u30F3\u30C9\u3092\u5F85\u6A5F\u305B\u305A\u306BVM\u3092\u5373\u6642\u306B\u8D77\u52D5\u3059\u308B\n -listconnectors \u3053\u306EVM\u3067\u4F7F\u7528\u53EF\u80FD\u306A\u30B3\u30CD\u30AF\u30BF\u3092\u30EA\u30B9\u30C8\u3059\u308B\n -connect <connector-name>:<name1>=<value1>,...\n \u6307\u5B9A\u3055\u308C\u305F\u30B3\u30CD\u30AF\u30BF\u3092\u4F7F\u7528\u3057\u3066\u3001\u30EA\u30B9\u30C8\u3055\u308C\u305F\u5F15\u6570\u5024\u3067\u30BF\u30FC\u30B2\u30C3\u30C8VM\u306B\u63A5\u7D9A\u3059\u308B\n -dbgtrace [flags] {0}\u306E\u30C7\u30D0\u30C3\u30B0\u306E\u60C5\u5831\u3092\u51FA\u529B\u3059\u308B\n -tclient \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092HotSpot(TM) Client Compiler\u3067\u5B9F\u884C\u3059\u308B\n -tserver \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092HotSpot(TM) Server Compiler\u3067\u5B9F\u884C\u3059\u308B\n\n\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u30C7\u30D0\u30C3\u30B0\u3059\u308B\u30D7\u30ED\u30BB\u30B9\u306B\u8EE2\u9001\u3055\u308C\u307E\u3059:\n -v -verbose[:class|gc|jni]\n \u8A73\u7D30\u30E2\u30FC\u30C9\u3092\u30AA\u30F3\u306B\u3059\u308B\n -D<name>=<value> \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n -classpath <directories separated by \"{1}\">\n \u30AF\u30E9\u30B9\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u30EA\u30B9\u30C8\u3059\u308B\n -X<option> \u975E\u6A19\u6E96\u306E\u30BF\u30FC\u30B2\u30C3\u30C8VM\u30AA\u30D7\u30B7\u30E7\u30F3\n\n<class>\u306F\u30C7\u30D0\u30C3\u30B0\u3092\u958B\u59CB\u3059\u308B\u30AF\u30E9\u30B9\u306E\u540D\u524D\u3067\u3059\n<arguments>\u306F<class>\u306Emain()\u30E1\u30BD\u30C3\u30C9\u306B\u6E21\u3055\u308C\u308B\u5F15\u6570\u3067\u3059\n\n\u30B3\u30DE\u30F3\u30C9\u306E\u30D8\u30EB\u30D7\u306B\u3064\u3044\u3066\u306F{0}\u30D7\u30ED\u30F3\u30D7\u30C8\u3067''help''\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044"},
// END OF MATERIAL TO LOCALIZE
--- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_zh_CN.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_zh_CN.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,6 +107,7 @@
{"Current thread isnt suspended.", "\u5F53\u524D\u7EBF\u7A0B\u672A\u6302\u8D77\u3002"},
{"Current thread not set.", "\u5F53\u524D\u7EBF\u7A0B\u672A\u8BBE\u7F6E\u3002"},
{"dbgtrace flag value must be an integer:", "dbgtrace \u6807\u8BB0\u503C\u5FC5\u987B\u4E3A\u6574\u6570: {0}"},
+ {"dbgtrace command value must be an integer:", "dbgtrace \u547D\u4EE4\u503C\u5FC5\u987B\u4E3A\u6574\u6570\uFF1A{0}"},
{"Deferring.", "\u6B63\u5728\u5EF6\u8FDF{0}\u3002\n\u5C06\u5728\u52A0\u8F7D\u7C7B\u540E\u8BBE\u7F6E\u3002"},
{"End of stack.", "\u5806\u6808\u7ED3\u675F\u3002"},
{"Error popping frame", "\u4F7F\u5E27\u51FA\u6808\u65F6\u51FA\u9519 - {0}"},
@@ -119,12 +120,14 @@
{"Exception occurred caught", "\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF: {0} (\u5C06\u5728\u4EE5\u4E0B\u4F4D\u7F6E\u6355\u83B7: {1})"},
{"Exception occurred uncaught", "\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF: {0} (\u672A\u6355\u83B7)"},
{"Exceptions caught:", "\u51FA\u73B0\u8FD9\u4E9B\u5F02\u5E38\u9519\u8BEF\u65F6\u4E2D\u65AD:"},
+ {"Expected at, in, or an integer <thread_id>:", "\u5E94\u4E3A \"at\"\u3001\"in\" \u6216\u4EE5\u6574\u6570\u8868\u793A\u7684 <thread_id>\uFF1A{0}"},
{"expr is null", "{0} = \u7A7A\u503C"},
{"expr is value", "{0} = {1}"},
{"expr is value <collected>", " {0} = {1} <\u5DF2\u6536\u96C6>"},
{"Expression cannot be void", "\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A"},
{"Expression must evaluate to an object", "\u8868\u8FBE\u5F0F\u7684\u8BA1\u7B97\u7ED3\u679C\u5FC5\u987B\u4E3A\u5BF9\u8C61"},
{"extends:", "\u6269\u5C55: {0}"},
+ {"Extra tokens after breakpoint location", "\u7AEF\u70B9\u4F4D\u7F6E\u540E\u9762\u6709\u989D\u5916\u7684\u6807\u8BB0"},
{"Failed reading output", "\u65E0\u6CD5\u8BFB\u53D6\u5B50 Java \u89E3\u91CA\u5668\u7684\u8F93\u51FA\u3002"},
{"Fatal error", "\u81F4\u547D\u9519\u8BEF:"},
{"Field access encountered before after", "\u5B57\u6BB5 ({0}) \u4E3A{1}, \u5C06\u4E3A{2}: "},
@@ -153,11 +156,14 @@
{"Invalid connect type", "\u8FDE\u63A5\u7C7B\u578B\u65E0\u6548"},
{"Invalid consecutive invocations", "\u8FDE\u7EED\u8C03\u7528\u65E0\u6548"},
{"Invalid exception object", "\u5F02\u5E38\u9519\u8BEF\u5BF9\u8C61\u65E0\u6548"},
- {"Invalid method specification:", "\u65B9\u6CD5\u89C4\u8303\u65E0\u6548: {0}"},
+ {"Invalid line number specified", "\u6307\u5B9A\u7684\u884C\u53F7\u65E0\u6548"},
+ {"Invalid <method_name> specification:", "<method_name> \u89C4\u8303\u65E0\u6548\uFF1A{0}"},
{"Invalid option on class command", "\u7C7B\u547D\u4EE4\u7684\u9009\u9879\u65E0\u6548"},
{"invalid option", "\u9009\u9879\u65E0\u6548: {0}"},
{"Invalid thread status.", "\u7EBF\u7A0B\u72B6\u6001\u65E0\u6548\u3002"},
+ {"Invalid <thread_id>:", "<thread_id> \u65E0\u6548\uFF1A{0}"},
{"Invalid transport name:", "\u4F20\u8F93\u540D\u79F0\u65E0\u6548: {0}"},
+ {"Invalid <class>.<method_name> specification", "<class>.<method_name> \u89C4\u8303\u65E0\u6548"},
{"I/O exception occurred:", "\u51FA\u73B0 I/O \u5F02\u5E38\u9519\u8BEF: {0}"},
{"is an ambiguous method name in", "\"{0}\" \u5728 \"{1}\" \u4E2D\u662F\u4E0D\u660E\u786E\u7684\u65B9\u6CD5\u540D\u79F0"},
{"is an invalid line number for", "{0,number,integer} \u662F{1}\u7684\u65E0\u6548\u884C\u53F7"},
@@ -190,6 +196,7 @@
{"Method exitedValue:", "\u5DF2\u9000\u51FA\u65B9\u6CD5: \u8FD4\u56DE\u503C = {0}, "},
{"Method is overloaded; specify arguments", "\u5DF2\u91CD\u8F7D\u65B9\u6CD5{0}; \u8BF7\u6307\u5B9A\u53C2\u6570"},
{"minus version", "\u8FD9\u662F{0}\u7248\u672C {1,number,integer}.{2,number,integer} (Java SE \u7248\u672C {3})"},
+ {"Missing at or in", "\u7F3A\u5C11 \"at\" \u6216 \"in\""},
{"Monitor information for thread", "\u76D1\u89C6\u7EBF\u7A0B{0}\u7684\u4FE1\u606F:"},
{"Monitor information for expr", "\u76D1\u89C6{0} ({1}) \u7684\u4FE1\u606F:"},
{"More than one class named", "\u591A\u4E2A\u7C7B\u7684\u540D\u79F0\u4E3A: ''{0}''"},
@@ -234,13 +241,16 @@
{"Not owned", " \u4E0D\u62E5\u6709"},
{"Not waiting for a monitor", " \u672A\u7B49\u5F85\u76D1\u89C6\u5668"},
{"Nothing suspended.", "\u672A\u6302\u8D77\u4EFB\u4F55\u5BF9\u8C61\u3002"},
- {"object description and hex id", "({0}){1}"},
+ {"object description and id", "({0}){1}"},
{"Operation is not supported on the target VM", "\u76EE\u6807 VM \u4E0D\u652F\u6301\u8BE5\u64CD\u4F5C"},
{"operation not yet supported", "\u5C1A\u4E0D\u652F\u6301\u8BE5\u64CD\u4F5C"},
{"Owned by:", " \u62E5\u6709\u8005: {0}, \u6761\u76EE\u8BA1\u6570: {1,number,integer}"},
{"Owned monitor:", " \u62E5\u6709\u7684\u76D1\u89C6\u5668: {0}"},
{"Parse exception:", "\u8BED\u6CD5\u5206\u6790\u5F02\u5E38\u9519\u8BEF: {0}"},
- {"printbreakpointcommandusage", "\u7528\u6CD5: {0} <class>:<line_number> \u6216\n {1} <class>.<method_name>[(argument_type,...)]"},
+ {"printclearcommandusage", "\u7528\u6CD5\uFF1Aclear <class>:<line_number> \u6216\n clear <class>.<method_name>[(argument_type,...)]"},
+ {"printstopcommandusage",
+ "\u7528\u6CD5\uFF1Astop [go|thread] [<thread_id>] <at|in> <location>\n \u5982\u679C\u6307\u5B9A \"go\"\uFF0C\u5219\u5728\u505C\u6B62\u540E\u7ACB\u5373\u6062\u590D\n \u5982\u679C\u6307\u5B9A \"thread\"\uFF0C\u5219\u4EC5\u6302\u8D77\u5728\u5176\u4E2D\u505C\u6B62\u7684\u7EBF\u7A0B\n \u5982\u679C\u65E2\u672A\u6307\u5B9A \"go\" \u4E5F\u672A\u6307\u5B9A \"thread\"\uFF0C\u5219\u6302\u8D77\u6240\u6709\u7EBF\u7A0B\n \u5982\u679C\u6307\u5B9A\u4EE5\u6574\u6570\u8868\u793A\u7684 <thread_id>\uFF0C\u5219\u4EC5\u5728\u6307\u5B9A\u7684\u7EBF\u7A0B\u4E2D\u505C\u6B62\n \"at\" \u548C \"in\" \u7684\u542B\u4E49\u76F8\u540C\n <location> \u53EF\u4EE5\u662F\u884C\u53F7\u6216\u65B9\u6CD5\uFF1A\n <class_id>:<line_number>\n <class_id>.<method>[(argument_type,...)]"
+ },
{"Removed:", "\u5DF2\u5220\u9664: {0}"},
{"Requested stack frame is no longer active:", "\u8BF7\u6C42\u7684\u5806\u6808\u5E27\u4E0D\u518D\u6709\u6548: {0,number,integer}"},
{"run <args> command is valid only with launched VMs", "'run <args>' \u547D\u4EE4\u4EC5\u5BF9\u542F\u52A8\u7684 VM \u6709\u6548"},
@@ -289,6 +299,8 @@
{"Thread not suspended", "\u672A\u6302\u8D77\u7EBF\u7A0B"},
{"thread group number description name", "{0,number,integer}\u3002{1} {2}"},
{"Threadgroup name not specified.", "\u672A\u6307\u5B9A\u7EBF\u7A0B\u7EC4\u540D\u3002"},
+ {"<thread_id> option not valid until the VM is started with the run command",
+ "\u5728\u4F7F\u7528 run \u547D\u4EE4\u542F\u52A8 VM \u524D\uFF0C<thread_id> \u9009\u9879\u65E0\u6548"},
{"Threads must be suspended", "\u5FC5\u987B\u6302\u8D77\u7EBF\u7A0B"},
{"trace method exit in effect for", "\u6B63\u5728\u5BF9{0}\u5B9E\u884C trace method exit"},
{"trace method exits in effect", "\u6B63\u5728\u5B9E\u884C trace method exits"},
@@ -315,7 +327,6 @@
{"Usage: unmonitor <monitor#>", "\u7528\u6CD5: unmonitor <monitor#>"},
{"Usage: up [n frames]", "\u7528\u6CD5: up [n frames]"},
{"Use java minus X to see", "\u4F7F\u7528 'java -X' \u53EF\u4EE5\u67E5\u770B\u53EF\u7528\u7684\u975E\u6807\u51C6\u9009\u9879"},
- {"Use stop at to set a breakpoint at a line number", "\u4F7F\u7528 'stop at' \u53EF\u4EE5\u5728\u884C\u53F7\u5904\u8BBE\u7F6E\u65AD\u70B9"},
{"VM already running. use cont to continue after events.", "VM \u5DF2\u5728\u8FD0\u884C\u3002\u8BF7\u4F7F\u7528 'cont' \u4EE5\u5728\u4E8B\u4EF6\u7ED3\u675F\u540E\u7EE7\u7EED\u3002"},
{"VM Started:", "VM \u5DF2\u542F\u52A8: "},
{"vmstartexception", "VM \u542F\u52A8\u5F02\u5E38\u9519\u8BEF: {0}"},
@@ -324,7 +335,7 @@
{"watch accesses of", "\u76D1\u89C6{0}.{1}\u7684\u8BBF\u95EE"},
{"watch modification of", "\u76D1\u89C6{0}.{1}\u7684\u4FEE\u6539"},
{"zz help text",
- "** \u547D\u4EE4\u5217\u8868 **\nconnectors -- \u5217\u51FA\u6B64 VM \u4E2D\u53EF\u7528\u7684\u8FDE\u63A5\u5668\u548C\u4F20\u8F93\n\nrun [class [args]] -- \u5F00\u59CB\u6267\u884C\u5E94\u7528\u7A0B\u5E8F\u7684\u4E3B\u7C7B\n\nthreads [threadgroup] -- \u5217\u51FA\u7EBF\u7A0B\nthread <thread id> -- \u8BBE\u7F6E\u9ED8\u8BA4\u7EBF\u7A0B\nsuspend [thread id(s)] -- \u6302\u8D77\u7EBF\u7A0B (\u9ED8\u8BA4\u503C: all)\nresume [thread id(s)] -- \u6062\u590D\u7EBF\u7A0B (\u9ED8\u8BA4\u503C: all)\nwhere [<thread id> | all] -- \u8F6C\u50A8\u7EBF\u7A0B\u7684\u5806\u6808\nwherei [<thread id> | all]-- \u8F6C\u50A8\u7EBF\u7A0B\u7684\u5806\u6808, \u4EE5\u53CA pc \u4FE1\u606F\nup [n frames] -- \u4E0A\u79FB\u7EBF\u7A0B\u7684\u5806\u6808\ndown [n frames] -- \u4E0B\u79FB\u7EBF\u7A0B\u7684\u5806\u6808\nkill <thread id> <expr> -- \u7EC8\u6B62\u5177\u6709\u7ED9\u5B9A\u7684\u5F02\u5E38\u9519\u8BEF\u5BF9\u8C61\u7684\u7EBF\u7A0B\ninterrupt <thread id> -- \u4E2D\u65AD\u7EBF\u7A0B\n\nprint <expr> -- \u8F93\u51FA\u8868\u8FBE\u5F0F\u7684\u503C\ndump <expr> -- \u8F93\u51FA\u6240\u6709\u5BF9\u8C61\u4FE1\u606F\neval <expr> -- \u5BF9\u8868\u8FBE\u5F0F\u6C42\u503C (\u4E0E print \u76F8\u540C)\nset <lvalue> = <expr> -- \u5411\u5B57\u6BB5/\u53D8\u91CF/\u6570\u7EC4\u5143\u7D20\u5206\u914D\u65B0\u503C\nlocals -- \u8F93\u51FA\u5F53\u524D\u5806\u6808\u5E27\u4E2D\u7684\u6240\u6709\u672C\u5730\u53D8\u91CF\n\nclasses -- \u5217\u51FA\u5F53\u524D\u5DF2\u77E5\u7684\u7C7B\nclass <class id> -- \u663E\u793A\u5DF2\u547D\u540D\u7C7B\u7684\u8BE6\u7EC6\u8D44\u6599\nmethods <class id> -- \u5217\u51FA\u7C7B\u7684\u65B9\u6CD5\nfields <class id> -- \u5217\u51FA\u7C7B\u7684\u5B57\u6BB5\n\nthreadgroups -- \u5217\u51FA\u7EBF\u7A0B\u7EC4\nthreadgroup <name> -- \u8BBE\u7F6E\u5F53\u524D\u7EBF\u7A0B\u7EC4\n\nstop in <class id>.<method>[(argument_type,...)]\n -- \u5728\u65B9\u6CD5\u4E2D\u8BBE\u7F6E\u65AD\u70B9\nstop at <class id>:<line> -- \u5728\u884C\u4E2D\u8BBE\u7F6E\u65AD\u70B9\nclear <class id>.<method>[(argument_type,...)]\n -- \u6E05\u9664\u65B9\u6CD5\u4E2D\u7684\u65AD\u70B9\nclear <class id>:<line> -- \u6E05\u9664\u884C\u4E2D\u7684\u65AD\u70B9\nclear -- \u5217\u51FA\u65AD\u70B9\ncatch [uncaught|caught|all] <class id>|<class pattern>\n -- \u51FA\u73B0\u6307\u5B9A\u7684\u5F02\u5E38\u9519\u8BEF\u65F6\u4E2D\u65AD\nignore [uncaught|caught|all] <class id>|<class pattern>\n -- \u5BF9\u4E8E\u6307\u5B9A\u7684\u5F02\u5E38\u9519\u8BEF, \u53D6\u6D88 'catch'\nwatch [access|all] <class id>.<field name>\n -- \u76D1\u89C6\u5BF9\u5B57\u6BB5\u7684\u8BBF\u95EE/\u4FEE\u6539\nunwatch [access|all] <class id>.<field name>\n -- \u505C\u6B62\u76D1\u89C6\u5BF9\u5B57\u6BB5\u7684\u8BBF\u95EE/\u4FEE\u6539\ntrace [go] methods [thread]\n -- \u8DDF\u8E2A\u65B9\u6CD5\u8FDB\u5165\u548C\u9000\u51FA\u3002\n -- \u9664\u975E\u6307\u5B9A 'go', \u5426\u5219\u6302\u8D77\u6240\u6709\u7EBF\u7A0B\ntrace [go] method exit | exits [thread]\n -- \u8DDF\u8E2A\u5F53\u524D\u65B9\u6CD5\u7684\u9000\u51FA, \u6216\u8005\u6240\u6709\u65B9\u6CD5\u7684\u9000\u51FA\n -- \u9664\u975E\u6307\u5B9A 'go', \u5426\u5219\u6302\u8D77\u6240\u6709\u7EBF\u7A0B\nuntrace [methods] -- \u505C\u6B62\u8DDF\u8E2A\u65B9\u6CD5\u8FDB\u5165\u548C/\u6216\u9000\u51FA\nstep -- \u6267\u884C\u5F53\u524D\u884C\nstep up -- \u4E00\u76F4\u6267\u884C, \u76F4\u5230\u5F53\u524D\u65B9\u6CD5\u8FD4\u56DE\u5230\u5176\u8C03\u7528\u65B9\nstepi -- \u6267\u884C\u5F53\u524D\u6307\u4EE4\n\u4E0B\u4E00\u6B65 -- \u6B65\u8FDB\u4E00\u884C (\u6B65\u8FC7\u8C03\u7528)\ncont -- \u4ECE\u65AD\u70B9\u5904\u7EE7\u7EED\u6267\u884C\n\nlist [line number|method] -- \u8F93\u51FA\u6E90\u4EE3\u7801\nuse (\u6216 sourcepath) [source file path]\n -- \u663E\u793A\u6216\u66F4\u6539\u6E90\u8DEF\u5F84\nexclude [<class pattern>, ... | \"none\"]\n -- \u5BF9\u4E8E\u6307\u5B9A\u7684\u7C7B, \u4E0D\u62A5\u544A\u6B65\u9AA4\u6216\u65B9\u6CD5\u4E8B\u4EF6\nclasspath -- \u4ECE\u76EE\u6807 VM \u8F93\u51FA\u7C7B\u8DEF\u5F84\u4FE1\u606F\n\nmonitor <command> -- \u6BCF\u6B21\u7A0B\u5E8F\u505C\u6B62\u65F6\u6267\u884C\u547D\u4EE4\nmonitor -- \u5217\u51FA\u76D1\u89C6\u5668\nunmonitor <monitor#> -- \u5220\u9664\u76D1\u89C6\u5668\nread <filename> -- \u8BFB\u53D6\u5E76\u6267\u884C\u547D\u4EE4\u6587\u4EF6\n\nlock <expr> -- \u8F93\u51FA\u5BF9\u8C61\u7684\u9501\u4FE1\u606F\nthreadlocks [thread id] -- \u8F93\u51FA\u7EBF\u7A0B\u7684\u9501\u4FE1\u606F\n\npop -- \u901A\u8FC7\u5F53\u524D\u5E27\u51FA\u6808, \u4E14\u5305\u542B\u5F53\u524D\u5E27\nreenter -- \u4E0E pop \u76F8\u540C, \u4F46\u91CD\u65B0\u8FDB\u5165\u5F53\u524D\u5E27\nredefine <class id> <class file name>\n -- \u91CD\u65B0\u5B9A\u4E49\u7C7B\u7684\u4EE3\u7801\n\ndisablegc <expr> -- \u7981\u6B62\u5BF9\u8C61\u7684\u5783\u573E\u6536\u96C6\nenablegc <expr> -- \u5141\u8BB8\u5BF9\u8C61\u7684\u5783\u573E\u6536\u96C6\n\n!! -- \u91CD\u590D\u6267\u884C\u6700\u540E\u4E00\u4E2A\u547D\u4EE4\n<n> <command> -- \u5C06\u547D\u4EE4\u91CD\u590D\u6267\u884C n \u6B21\n# <command> -- \u653E\u5F03 (\u65E0\u64CD\u4F5C)\nhelp (\u6216 ?) -- \u5217\u51FA\u547D\u4EE4\nversion -- \u8F93\u51FA\u7248\u672C\u4FE1\u606F\nexit (\u6216 quit) -- \u9000\u51FA\u8C03\u8BD5\u5668\n\n<class id>: \u5E26\u6709\u7A0B\u5E8F\u5305\u9650\u5B9A\u7B26\u7684\u5B8C\u6574\u7C7B\u540D\n<class pattern>: \u5E26\u6709\u524D\u5BFC\u6216\u5C3E\u968F\u901A\u914D\u7B26 ('*') \u7684\u7C7B\u540D\n<thread id>: 'threads' \u547D\u4EE4\u4E2D\u62A5\u544A\u7684\u7EBF\u7A0B\u7F16\u53F7\n<expr>: Java(TM) \u7F16\u7A0B\u8BED\u8A00\u8868\u8FBE\u5F0F\u3002\n\u652F\u6301\u5927\u591A\u6570\u5E38\u89C1\u8BED\u6CD5\u3002\n\n\u53EF\u4EE5\u5C06\u542F\u52A8\u547D\u4EE4\u7F6E\u4E8E \"jdb.ini\" \u6216 \".jdbrc\" \u4E2D\n\u4F4D\u4E8E user.home \u6216 user.dir \u4E2D"},
+ "** \u547D\u4EE4\u5217\u8868 **\nconnectors -- \u5217\u51FA\u6B64 VM \u4E2D\u53EF\u7528\u7684\u8FDE\u63A5\u5668\u548C\u4F20\u8F93\n\nrun [class [args]] -- \u5F00\u59CB\u6267\u884C\u5E94\u7528\u7A0B\u5E8F\u7684\u4E3B\u7C7B\n\nthreads [threadgroup] -- \u5217\u51FA\u7EBF\u7A0B\nthread <thread id> -- \u8BBE\u7F6E\u9ED8\u8BA4\u7EBF\u7A0B\nsuspend [thread id(s)] -- \u6302\u8D77\u7EBF\u7A0B (\u9ED8\u8BA4\u503C: all)\nresume [thread id(s)] -- \u6062\u590D\u7EBF\u7A0B (\u9ED8\u8BA4\u503C: all)\nwhere [<thread id> | all] -- \u8F6C\u50A8\u7EBF\u7A0B\u7684\u5806\u6808\nwherei [<thread id> | all]-- \u8F6C\u50A8\u7EBF\u7A0B\u7684\u5806\u6808, \u4EE5\u53CA pc \u4FE1\u606F\nup [n frames] -- \u4E0A\u79FB\u7EBF\u7A0B\u7684\u5806\u6808\ndown [n frames] -- \u4E0B\u79FB\u7EBF\u7A0B\u7684\u5806\u6808\nkill <thread id> <expr> -- \u7EC8\u6B62\u5177\u6709\u7ED9\u5B9A\u7684\u5F02\u5E38\u9519\u8BEF\u5BF9\u8C61\u7684\u7EBF\u7A0B\ninterrupt <thread id> -- \u4E2D\u65AD\u7EBF\u7A0B\n\nprint <expr> -- \u8F93\u51FA\u8868\u8FBE\u5F0F\u7684\u503C\ndump <expr> -- \u8F93\u51FA\u6240\u6709\u5BF9\u8C61\u4FE1\u606F\neval <expr> -- \u5BF9\u8868\u8FBE\u5F0F\u6C42\u503C (\u4E0E print \u76F8\u540C)\nset <lvalue> = <expr> -- \u5411\u5B57\u6BB5/\u53D8\u91CF/\u6570\u7EC4\u5143\u7D20\u5206\u914D\u65B0\u503C\nlocals -- \u8F93\u51FA\u5F53\u524D\u5806\u6808\u5E27\u4E2D\u7684\u6240\u6709\u672C\u5730\u53D8\u91CF\n\nclasses -- \u5217\u51FA\u5F53\u524D\u5DF2\u77E5\u7684\u7C7B\nclass <class id> -- \u663E\u793A\u5DF2\u547D\u540D\u7C7B\u7684\u8BE6\u7EC6\u8D44\u6599\nmethods <class id> -- \u5217\u51FA\u7C7B\u7684\u65B9\u6CD5\nfields <class id> -- \u5217\u51FA\u7C7B\u7684\u5B57\u6BB5\n\nthreadgroups -- \u5217\u51FA\u7EBF\u7A0B\u7EC4\nthreadgroup <name> -- \u8BBE\u7F6E\u5F53\u524D\u7EBF\u7A0B\u7EC4\n\nstop [go|thread] [<thread_id>] <at|in> <location>\n -- \u8BBE\u7F6E\u65AD\u70B9\n -- \u5982\u679C\u672A\u63D0\u4F9B\u4EFB\u4F55\u9009\u9879\uFF0C\u5219\u5C06\u6253\u5370\u5F53\u524D\u65AD\u70B9\u5217\u8868\n -- \u5982\u679C\u6307\u5B9A \"go\"\uFF0C\u5219\u5728\u505C\u6B62\u540E\u7ACB\u5373\u6062\u590D\n -- \u5982\u679C\u6307\u5B9A \"thread\"\uFF0C\u5219\u4EC5\u6302\u8D77\u5728\u5176\u4E2D\u505C\u6B62\u7684\u7EBF\u7A0B\n -- \u5982\u679C\u65E2\u672A\u6307\u5B9A \"go\" \u4E5F\u672A\u6307\u5B9A \"thread\"\uFF0C\u5219\u6302\u8D77\u6240\u6709\u7EBF\u7A0B\n -- \u5982\u679C\u6307\u5B9A\u4EE5\u6574\u6570\u8868\u793A\u7684 <thread_id>\uFF0C\u5219\u4EC5\u5728\u6307\u5B9A\u7684\u7EBF\u7A0B\u4E2D\u505C\u6B62\n -- \"at\" \u548C \"in\" \u7684\u542B\u4E49\u76F8\u540C\n -- <location> \u53EF\u4EE5\u662F\u884C\u53F7\u6216\u65B9\u6CD5\uFF1A\n -- <class_id>:<line_number>\n -- <class_id>.<method>[(argument_type,...)]\nclear <class id>.<method>[(argument_type,...)]\n -- \u6E05\u9664\u65B9\u6CD5\u4E2D\u7684\u65AD\u70B9\nclear <class id>:<line> -- \u6E05\u9664\u884C\u4E2D\u7684\u65AD\u70B9\nclear -- \u5217\u51FA\u65AD\u70B9\ncatch [uncaught|caught|all] <class id>|<class pattern>\n -- \u51FA\u73B0\u6307\u5B9A\u7684\u5F02\u5E38\u9519\u8BEF\u65F6\u4E2D\u65AD\nignore [uncaught|caught|all] <class id>|<class pattern>\n -- \u5BF9\u4E8E\u6307\u5B9A\u7684\u5F02\u5E38\u9519\u8BEF, \u53D6\u6D88 'catch'\nwatch [access|all] <class id>.<field name>\n -- \u76D1\u89C6\u5BF9\u5B57\u6BB5\u7684\u8BBF\u95EE/\u4FEE\u6539\nunwatch [access|all] <class id>.<field name>\n -- \u505C\u6B62\u76D1\u89C6\u5BF9\u5B57\u6BB5\u7684\u8BBF\u95EE/\u4FEE\u6539\ntrace [go] methods [thread]\n -- \u8DDF\u8E2A\u65B9\u6CD5\u8FDB\u5165\u548C\u9000\u51FA\u3002\n -- \u9664\u975E\u6307\u5B9A 'go', \u5426\u5219\u6302\u8D77\u6240\u6709\u7EBF\u7A0B\ntrace [go] method exit | exits [thread]\n -- \u8DDF\u8E2A\u5F53\u524D\u65B9\u6CD5\u7684\u9000\u51FA, \u6216\u8005\u6240\u6709\u65B9\u6CD5\u7684\u9000\u51FA\n -- \u9664\u975E\u6307\u5B9A 'go', \u5426\u5219\u6302\u8D77\u6240\u6709\u7EBF\u7A0B\nuntrace [methods] -- \u505C\u6B62\u8DDF\u8E2A\u65B9\u6CD5\u8FDB\u5165\u548C/\u6216\u9000\u51FA\nstep -- \u6267\u884C\u5F53\u524D\u884C\nstep up -- \u4E00\u76F4\u6267\u884C, \u76F4\u5230\u5F53\u524D\u65B9\u6CD5\u8FD4\u56DE\u5230\u5176\u8C03\u7528\u65B9\nstepi -- \u6267\u884C\u5F53\u524D\u6307\u4EE4\n\u4E0B\u4E00\u6B65 -- \u6B65\u8FDB\u4E00\u884C (\u6B65\u8FC7\u8C03\u7528)\ncont -- \u4ECE\u65AD\u70B9\u5904\u7EE7\u7EED\u6267\u884C\n\nlist [line number|method] -- \u8F93\u51FA\u6E90\u4EE3\u7801\nuse (\u6216 sourcepath) [source file path]\n -- \u663E\u793A\u6216\u66F4\u6539\u6E90\u8DEF\u5F84\nexclude [<class pattern>, ... | \"none\"]\n -- \u5BF9\u4E8E\u6307\u5B9A\u7684\u7C7B, \u4E0D\u62A5\u544A\u6B65\u9AA4\u6216\u65B9\u6CD5\u4E8B\u4EF6\nclasspath -- \u4ECE\u76EE\u6807 VM \u8F93\u51FA\u7C7B\u8DEF\u5F84\u4FE1\u606F\n\nmonitor <command> -- \u6BCF\u6B21\u7A0B\u5E8F\u505C\u6B62\u65F6\u6267\u884C\u547D\u4EE4\nmonitor -- \u5217\u51FA\u76D1\u89C6\u5668\nunmonitor <monitor#> -- \u5220\u9664\u76D1\u89C6\u5668\nread <filename> -- \u8BFB\u53D6\u5E76\u6267\u884C\u547D\u4EE4\u6587\u4EF6\n\nlock <expr> -- \u8F93\u51FA\u5BF9\u8C61\u7684\u9501\u4FE1\u606F\nthreadlocks [thread id] -- \u8F93\u51FA\u7EBF\u7A0B\u7684\u9501\u4FE1\u606F\n\npop -- \u901A\u8FC7\u5F53\u524D\u5E27\u51FA\u6808, \u4E14\u5305\u542B\u5F53\u524D\u5E27\nreenter -- \u4E0E pop \u76F8\u540C, \u4F46\u91CD\u65B0\u8FDB\u5165\u5F53\u524D\u5E27\nredefine <class id> <class file name>\n -- \u91CD\u65B0\u5B9A\u4E49\u7C7B\u7684\u4EE3\u7801\n\ndisablegc <expr> -- \u7981\u6B62\u5BF9\u8C61\u7684\u5783\u573E\u6536\u96C6\nenablegc <expr> -- \u5141\u8BB8\u5BF9\u8C61\u7684\u5783\u573E\u6536\u96C6\n\n!! -- \u91CD\u590D\u6267\u884C\u6700\u540E\u4E00\u4E2A\u547D\u4EE4\n<n> <command> -- \u5C06\u547D\u4EE4\u91CD\u590D\u6267\u884C n \u6B21\n# <command> -- \u653E\u5F03 (\u65E0\u64CD\u4F5C)\nhelp (\u6216 ?) -- \u5217\u51FA\u547D\u4EE4\ndbgtrace [flag] -- \u4E0E dbgtrace \u547D\u4EE4\u884C\u9009\u9879\u76F8\u540C\nversion -- \u8F93\u51FA\u7248\u672C\u4FE1\u606F\nexit (\u6216 quit) -- \u9000\u51FA\u8C03\u8BD5\u5668\n\n<class id>: \u5E26\u6709\u7A0B\u5E8F\u5305\u9650\u5B9A\u7B26\u7684\u5B8C\u6574\u7C7B\u540D\n<class pattern>: \u5E26\u6709\u524D\u5BFC\u6216\u5C3E\u968F\u901A\u914D\u7B26 ('*') \u7684\u7C7B\u540D\n<thread id>: 'threads' \u547D\u4EE4\u4E2D\u62A5\u544A\u7684\u7EBF\u7A0B\u7F16\u53F7\n<expr>: Java(TM) \u7F16\u7A0B\u8BED\u8A00\u8868\u8FBE\u5F0F\u3002\n\u652F\u6301\u5927\u591A\u6570\u5E38\u89C1\u8BED\u6CD5\u3002\n\n\u53EF\u4EE5\u5C06\u542F\u52A8\u547D\u4EE4\u7F6E\u4E8E \"jdb.ini\" \u6216 \".jdbrc\" \u4E2D\n\u4F4D\u4E8E user.home \u6216 user.dir \u4E2D"},
{"zz usage text",
"\u7528\u6CD5\uFF1A{0} <\u9009\u9879> <\u7C7B> <\u53C2\u6570>\n\n\u5176\u4E2D\uFF0C\u9009\u9879\u5305\u62EC\uFF1A\n -? -h --help -help \u8F93\u51FA\u6B64\u6D88\u606F\u5E76\u9000\u51FA\n -sourcepath <\u7531 \"{1}\" \u5206\u9694\u7684\u76EE\u5F55>\n \u8981\u5728\u5176\u4E2D\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u76EE\u5F55\n -attach <\u5730\u5740>\n \u4F7F\u7528\u6807\u51C6\u8FDE\u63A5\u5668\u9644\u52A0\u5230\u6307\u5B9A\u5730\u5740\u5904\u6B63\u5728\u8FD0\u884C\u7684 VM\n -listen <\u5730\u5740>\n \u7B49\u5F85\u6B63\u5728\u8FD0\u884C\u7684 VM \u4F7F\u7528\u6807\u51C6\u8FDE\u63A5\u5668\u5728\u6307\u5B9A\u5730\u5740\u5904\u8FDE\u63A5\n -listenany\n \u7B49\u5F85\u6B63\u5728\u8FD0\u884C\u7684 VM \u4F7F\u7528\u6807\u51C6\u8FDE\u63A5\u5668\u5728\u4EFB\u4F55\u53EF\u7528\u5730\u5740\u5904\u8FDE\u63A5\n -launch\n \u7ACB\u5373\u542F\u52A8 VM \u800C\u4E0D\u662F\u7B49\u5F85 ''run'' \u547D\u4EE4\n -listconnectors \u5217\u51FA\u6B64 VM \u4E2D\u7684\u53EF\u7528\u8FDE\u63A5\u5668\n -connect <\u8FDE\u63A5\u5668\u540D\u79F0>:<\u540D\u79F0 1>=<\u503C 1>,...\n \u4F7F\u7528\u6240\u5217\u53C2\u6570\u503C\u901A\u8FC7\u6307\u5B9A\u7684\u8FDE\u63A5\u5668\u8FDE\u63A5\u5230\u76EE\u6807 VM\n -dbgtrace [flags] \u8F93\u51FA\u8C03\u8BD5 {0} \u7684\u4FE1\u606F\n -tclient \u5728 HotSpot(TM) \u5BA2\u6237\u673A\u7F16\u8BD1\u5668\u4E2D\u8FD0\u884C\u5E94\u7528\u7A0B\u5E8F\n -tserver \u5728 HotSpot(TM) \u670D\u52A1\u5668\u7F16\u8BD1\u5668\u4E2D\u8FD0\u884C\u5E94\u7528\u7A0B\u5E8F\n\n\u8F6C\u53D1\u5230\u88AB\u8C03\u8BD5\u8FDB\u7A0B\u7684\u9009\u9879\uFF1A\n -v -verbose[:class|gc|jni]\n \u542F\u7528\u8BE6\u7EC6\u6A21\u5F0F\n -D<\u540D\u79F0>=<\u503C> \u8BBE\u7F6E\u7CFB\u7EDF\u5C5E\u6027\n -classpath <\u7531 \"{1}\" \u5206\u9694\u7684\u76EE\u5F55>\n \u5217\u51FA\u8981\u5728\u5176\u4E2D\u67E5\u627E\u7C7B\u7684\u76EE\u5F55\n -X<\u9009\u9879> \u975E\u6807\u51C6\u76EE\u6807 VM \u9009\u9879\n\n<\u7C7B> \u662F\u8981\u5F00\u59CB\u8C03\u8BD5\u7684\u7C7B\u7684\u540D\u79F0\n<\u53C2\u6570> \u662F\u4F20\u9012\u5230 <\u7C7B> \u7684 main() \u65B9\u6CD5\u7684\u53C2\u6570\n\n\u8981\u83B7\u5F97\u547D\u4EE4\u7684\u5E2E\u52A9\uFF0C\u8BF7\u5728 {0} \u63D0\u793A\u4E0B\u952E\u5165 ''help''"},
// END OF MATERIAL TO LOCALIZE
--- a/src/jdk.jlink/share/man/jlink.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jlink/share/man/jlink.1 Mon Jul 22 11:08:27 2019 +0530
@@ -379,9 +379,7 @@
The following command is similar to the one that creates a runtime image
named \f[CB]greetingsapp\f[R], except that it will link the modules
resolved from root modules with service binding; see the
-\f[B]\f[BC]Configuration.resolveAndBind\f[B]\f[R]
-[https://docs.oracle.com/javase/10/docs/api/java/lang/module/Configuration.html#resolveAndBind\-java.lang.module.ModuleFinder\-java.util.List\-java.lang.module.ModuleFinder\-java.util.Collection\-]
-method.
+\f[B]\f[BC]Configuration.resolveAndBind\f[B]\f[R] method.
.IP
.nf
\f[CB]
--- a/src/jdk.jlink/share/man/jmod.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.jlink/share/man/jmod.1 Mon Jul 22 11:08:27 2019 +0530
@@ -148,13 +148,10 @@
.IP \[bu] 2
\f[CB]regex:\f[R]\f[I]regex\-pattern\f[R]
.PP
-See the \f[B]\f[BC]FileSystem.getPathMatcher\f[B]\f[R]
-[https://docs.oracle.com/javase/10/docs/api/java/nio/file/FileSystem.html#getPathMatcher\-java.lang.String\-]
-method for the syntax of \f[I]glob\-pattern\f[R].
-See the \f[B]\f[BC]Pattern\f[B]\f[R]
-[https://docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html]
-class for the syntax of \f[I]regex\-pattern\f[R], which represents a
-regular expression.
+See the \f[B]\f[BC]FileSystem.getPathMatcher\f[B]\f[R] method for the
+syntax of \f[I]glob\-pattern\f[R].
+See the \f[B]\f[BC]Pattern\f[B]\f[R] class for the syntax of
+\f[I]regex\-pattern\f[R], which represents a regular expression.
.RE
.TP
.B \f[CB]\-\-hash\-modules\f[R] \f[I]regex\-pattern\f[R]
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java Mon Jul 22 11:08:27 2019 +0530
@@ -97,6 +97,10 @@
"\u6c11\u56fd\u524d",
"\u6c11\u56fd",
};
+ final String[] gregoryEras = {
+ "\u7d00\u5143\u524d",
+ "\u897f\u66a6",
+ };
return new Object[][] {
{ "MonthNames",
new String[] {
@@ -171,12 +175,8 @@
"\u5348\u5f8c" // pm marker
}
},
- { "Eras",
- new String[] { // era strings for GregorianCalendar
- "\u7d00\u5143\u524d",
- "\u897f\u66a6"
- }
- },
+ { "Eras", gregoryEras },
+ { "short.Eras", gregoryEras },
{ "buddhist.Eras",
new String[] { // era strings for Thai Buddhist calendar
"\u7d00\u5143\u524d", // Kigenzen
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_zh.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_zh.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -88,6 +88,10 @@
"\u6c11\u56fd\u524d",
"\u6c11\u56fd",
};
+ final String[] gregoryEras = {
+ "\u516c\u5143\u524d",
+ "\u516c\u5143",
+ };
return new Object[][] {
{ "MonthNames",
new String[] {
@@ -263,12 +267,8 @@
"\u4e0b\u5348" // pm marker
}
},
- { "Eras",
- new String[] { // era strings
- "\u516c\u5143\u524d",
- "\u516c\u5143"
- }
- },
+ { "Eras", gregoryEras },
+ { "short.Eras", gregoryEras },
{ "buddhist.Eras",
new String[] {
"BC",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_zh_TW.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_zh_TW.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -88,13 +88,13 @@
"\u6c11\u570b\u524d",
"\u6c11\u570b",
};
+ final String[] gregoryEras = {
+ "\u897f\u5143\u524d",
+ "\u897f\u5143",
+ };
return new Object[][] {
- { "Eras",
- new String[] { // era strings
- "\u897f\u5143\u524d",
- "\u897f\u5143"
- }
- },
+ { "Eras", gregoryEras },
+ { "short.Eras", gregoryEras },
{ "standalone.MonthAbbreviations",
new String[] {
"1\u6708",
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
{"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT},
- {"Africa/Sao_Tome", WAT},
+ {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET},
{"Africa/Tunis", CET},
--- a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,9 +95,14 @@
private static native boolean keepAliveOptionsSupported0();
private static native boolean quickAckSupported0();
static {
- AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ if (System.getSecurityManager() == null) {
System.loadLibrary("extnet");
- return null;
- });
+ } else {
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ System.loadLibrary("extnet");
+ return null;
+ });
+ }
}
-}
\ No newline at end of file
+}
+
--- a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,9 +77,13 @@
private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException;
private static native boolean keepAliveOptionsSupported0();
static {
- AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ if (System.getSecurityManager() == null) {
System.loadLibrary("extnet");
- return null;
- });
+ } else {
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ System.loadLibrary("extnet");
+ return null;
+ });
+ }
}
}
--- a/src/jdk.net/solaris/classes/jdk/net/SolarisSocketOptions.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.net/solaris/classes/jdk/net/SolarisSocketOptions.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,12 +45,16 @@
private static native void init();
static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("extnet");
- return null;
- }
- });
+ if (System.getSecurityManager() == null) {
+ System.loadLibrary("extnet");
+ } else {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("extnet");
+ return null;
+ }
+ });
+ }
init();
}
}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,6 +1,6 @@
#
#
-# Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -108,4 +108,4 @@
rmic.must.implement.remote.directly=\u30B9\u30BF\u30D6\u3092\u5FC5\u8981\u3068\u3059\u308B\u306E\u306Fjava.rmi.Remote\u3092\u62E1\u5F35\u3059\u308B\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3092\u76F4\u63A5\u5B9F\u88C5\u3059\u308B\u30AF\u30E9\u30B9\u306E\u307F\u3067\u3059\u3002\u30AF\u30E9\u30B9{0}\u306F\u30EA\u30E2\u30FC\u30C8\u30FB\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3092\u76F4\u63A5\u306B\u306F\u5B9F\u88C5\u3057\u307E\u305B\u3093\u3002
rmic.must.throw.remoteexception={0}\u306F\u4E0D\u6B63\u306A\u30EA\u30E2\u30FC\u30C8\u30FB\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3067\u3059\u3002\u30E1\u30BD\u30C3\u30C9{1}\u306Fjava.rmi.RemoteException\u3092\u30B9\u30ED\u30FC\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
rmic.must.only.throw.exception=\u30E1\u30BD\u30C3\u30C9{0}\u306F{1}\u3092\u30B9\u30ED\u30FC\u3059\u308B\u306E\u3067\u4E0D\u6B63\u306A\u30EA\u30E2\u30FC\u30C8\u30FB\u30E1\u30BD\u30C3\u30C9\u5B9F\u88C5\u3067\u3059\u3002\u30EA\u30E2\u30FC\u30C8\u30FB\u30E1\u30BD\u30C3\u30C9\u306E\u5B9F\u88C5\u304C\u30B9\u30ED\u30FC\u3059\u308B\u306E\u306Fjava.lang.Exception\u304B\u305D\u306E\u30B5\u30D6\u30AF\u30E9\u30B9\u306E\u307F\u3067\u3059\u3002
-rmic.jrmp.stubs.deprecated=\u8B66\u544A: JRMP\u306E\u30B9\u30B1\u30EB\u30C8\u30F3\u3068static\u30B9\u30BF\u30D6\u306E\u751F\u6210\u3068\u4F7F\u7528\u306F\n\u975E\u63A8\u5968\u3067\u3059\u3002\u30B9\u30B1\u30EB\u30C8\u30F3\u306F\u4E0D\u8981\u3067\u3001static\u30B9\u30BF\u30D6\u306F\n\u52D5\u7684\u306B\u751F\u6210\u3055\u308C\u308B\u30B9\u30BF\u30D6\u306B\u5DEE\u3057\u66FF\u3048\u3089\u308C\u307E\u3057\u305F\u3002\u30E6\u30FC\u30B6\u30FC\u306F\n\u30B9\u30B1\u30EB\u30C8\u30F3\u3068static\u30B9\u30BF\u30D6\u3092\u751F\u6210\u3059\u308B\u305F\u3081\u306B{0}\u3092\u4F7F\u7528\u305B\u305A\u306B\u79FB\u884C\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002\njava.rmi.server.UnicastRemoteObject\u306B\u95A2\u3059\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
+rmic.jrmp.stubs.deprecated=\u8B66\u544A: {0}\u306F\u975E\u63A8\u5968\u306B\u306A\u308A\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u307E\u3059\u3002\nJRMP\u306E\u30B9\u30B1\u30EB\u30C8\u30F3\u3068static\u30B9\u30BF\u30D6\u306E\u751F\u6210\u3068\u4F7F\u7528\u306F\n\u975E\u63A8\u5968\u3067\u3059\u3002\u30B9\u30B1\u30EB\u30C8\u30F3\u306F\u4E0D\u8981\u3067\u3001static\u30B9\u30BF\u30D6\u306F\n\u52D5\u7684\u306B\u751F\u6210\u3055\u308C\u308B\u30B9\u30BF\u30D6\u306B\u5DEE\u3057\u66FF\u3048\u3089\u308C\u307E\u3057\u305F\u3002\u30E6\u30FC\u30B6\u30FC\u306F\n\u30B9\u30B1\u30EB\u30C8\u30F3\u3068static\u30B9\u30BF\u30D6\u3092\u751F\u6210\u3059\u308B\u305F\u3081\u306B\u3053\u306E\u30C4\u30FC\u30EB\u3092\u4F7F\u7528\u305B\u305A\u306B\u79FB\u884C\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002\njava.rmi.server.UnicastRemoteObject\u306B\u95A2\u3059\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.rmic/share/classes/sun/rmi/rmic/resources/rmic_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,6 +1,6 @@
#
#
-# Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -108,4 +108,4 @@
rmic.must.implement.remote.directly=\u4EC5\u76F4\u63A5\u5B9E\u73B0\u6269\u5C55 java.rmi.Remote \u7684\u63A5\u53E3\u7684\u7C7B\u9700\u8981\u5B58\u6839; \u7C7B{0}\u4E0D\u76F4\u63A5\u5B9E\u73B0\u8FDC\u7A0B\u63A5\u53E3\u3002
rmic.must.throw.remoteexception={0}\u4E0D\u662F\u6709\u6548\u8FDC\u7A0B\u63A5\u53E3: \u65B9\u6CD5{1}\u5FC5\u987B\u629B\u51FA java.rmi.RemoteException\u3002
rmic.must.only.throw.exception=\u65B9\u6CD5{0}\u4E0D\u662F\u6709\u6548\u7684\u8FDC\u7A0B\u65B9\u6CD5\u5B9E\u73B0, \u56E0\u4E3A\u5B83\u629B\u51FA\u4E86{1}; \u8FDC\u7A0B\u65B9\u6CD5\u5B9E\u73B0\u53EA\u53EF\u80FD\u629B\u51FA java.lang.Exception \u6216\u5176\u5B50\u7C7B\u3002
-rmic.jrmp.stubs.deprecated=\u8B66\u544A: \u4E3A JRMP \u751F\u6210\u548C\u4F7F\u7528\u9AA8\u67B6\u53CA\u9759\u6001\u5B58\u6839\n\u5DF2\u8FC7\u65F6\u3002\u9AA8\u67B6\u4E0D\u518D\u5FC5\u8981, \u800C\u9759\u6001\u5B58\u6839\n\u5DF2\u7531\u52A8\u6001\u751F\u6210\u7684\u5B58\u6839\u53D6\u4EE3\u3002\u5EFA\u8BAE\u7528\u6237\n\u4E0D\u518D\u4F7F\u7528{0}\u6765\u751F\u6210\u9AA8\u67B6\u548C\u9759\u6001\u5B58\u6839\u3002\n\u8BF7\u53C2\u9605 java.rmi.server.UnicastRemoteObject \u7684\u6587\u6863\u3002
+rmic.jrmp.stubs.deprecated=\u8B66\u544A\uFF1A{0} \u5DF2\u8FC7\u65F6\uFF0C\u5C06\u4ECE\u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664\u3002\n\u4E3A JRMP \u751F\u6210\u548C\u4F7F\u7528\u9AA8\u67B6\u53CA\u9759\u6001\u5B58\u6839\u5DF2\u8FC7\u65F6\u3002\n\u9AA8\u67B6\u4E0D\u518D\u5FC5\u8981\uFF0C\u800C\u9759\u6001\u5B58\u6839\u5DF2\u7531\u52A8\u6001\u751F\u6210\u7684\u5B58\u6839\u53D6\u4EE3\u3002\n\u5EFA\u8BAE\u7528\u6237\u4E0D\u518D\u4F7F\u7528\u6B64\u5DE5\u5177\u6765\u751F\u6210\u9AA8\u67B6\u548C\u9759\u6001\u5B58\u6839\u3002\n\u8BF7\u53C2\u9605\u6709\u5173 java.rmi.server.UnicastRemoteObject \n\u7684\u6587\u6863\u3002
--- a/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_ja.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_ja.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -286,6 +286,7 @@
#
javac.err.version.too.old=\u30E1\u30B8\u30E3\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3''{0}''\u306F\u53E4\u3044\u305F\u3081\u3001\u3053\u306E\u30C4\u30FC\u30EB\u3067\u306F\u8A8D\u8B58\u3067\u304D\u307E\u305B\u3093\u3002
javac.err.version.too.recent=\u30E1\u30B8\u30E3\u30FC.\u30DE\u30A4\u30CA\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3''{0}''\u306F\u65B0\u3057\u3044\u305F\u3081\u3001\u3053\u306E\u30C4\u30FC\u30EB\u3067\u306F\u8A8D\u8B58\u3067\u304D\u307E\u305B\u3093\u3002
+javac.err.version.preview=\u30E1\u30B8\u30E3\u30FC.\u30DE\u30A4\u30CA\u30FC\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3''{0}''\u306F\u3001\u3053\u306E\u30C4\u30FC\u30EB\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D7\u30EC\u30D3\u30E5\u30FC\u6A5F\u80FD\u3092\u6709\u52B9\u306B\u3057\u3066\u30AF\u30E9\u30B9\u304C\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u305F\u3053\u3068\u3092\u793A\u3057\u307E\u3059\u3002
#
benv.parsed_in=[{0}\u3092{1}\u30DF\u30EA\u79D2\u3067\u69CB\u6587\u89E3\u6790\u3057\u307E\u3057\u305F]
benv.loaded_in=[{0}\u3092{1}\u30DF\u30EA\u79D2\u3067\u8AAD\u307F\u8FBC\u307F\u307E\u3057\u305F]
--- a/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_zh_CN.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_zh_CN.properties Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -286,6 +286,7 @@
#
javac.err.version.too.old=\u4E3B\u7248\u672C ''{0}'' \u592A\u65E7, \u6B64\u5DE5\u5177\u65E0\u6CD5\u8BC6\u522B\u3002
javac.err.version.too.recent=major.minor \u7248\u672C ''{0}'' \u592A\u65B0, \u6B64\u5DE5\u5177\u65E0\u6CD5\u8BC6\u522B\u3002
+javac.err.version.preview=major.minor \u7248\u672C ''{0}'' \u6307\u793A\u8BE5\u7C7B\u662F\u5728\u542F\u7528\u9884\u89C8\u529F\u80FD\u7684\u60C5\u51B5\u4E0B\u7F16\u8BD1\u7684\uFF0C\u4F46\u6B64\u5DE5\u5177\u4E0D\u652F\u6301\u3002
#
benv.parsed_in=[\u5DF2\u5728 {1} \u6BEB\u79D2\u5185\u5BF9{0}\u8FDB\u884C\u8BED\u6CD5\u5206\u6790]
benv.loaded_in=[\u5DF2\u5728 {1} \u6BEB\u79D2\u5185\u52A0\u8F7D{0}]
--- a/src/jdk.rmic/share/man/rmic.1 Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.rmic/share/man/rmic.1 Mon Jul 22 11:08:27 2019 +0530
@@ -46,12 +46,12 @@
.RE
.SH DESCRIPTION
.PP
-\f[B]Deprecation Note:\f[R] The \f[CB]rmic\f[R] tool has been deprecated and
-is subject to removal in a future release. Support for static
-generation of Java Remote Method Protocol (JRMP) stubs and skeletons
-has been deprecated. Applications should use dynamically generated
-JRMP stubs, eliminating the need to use the \f[CB]rmic\f[R] tool for
-JRMP-based applications.
+\f[B]Deprecation Note:\f[R] The rmic tool has been deprecated and is
+subject to removal in a future release.
+Support for static generation of Java Remote Method Protocol (JRMP)
+stubs and skeletons has been deprecated.
+Applications should use dynamically generated JRMP stubs, eliminating
+the need to use the rmic tool for JRMP\-based applications.
.PP
The \f[CB]rmic\f[R] compiler generates stub and skeleton class files using
the JRMP.
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/Bignum.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/Bignum.java Mon Jul 22 11:08:27 2019 +0530
@@ -76,13 +76,10 @@
// grow. There are no checks if the stack-allocated space is sufficient.
static final int kBigitCapacity = kMaxSignificantBits / kBigitSize;
- private final int[] bigits_ = new int[kBigitCapacity];
- // A vector backed by bigits_buffer_. This way accesses to the array are
- // checked for out-of-bounds errors.
- // Vector<int> bigits_;
private int used_digits_;
// The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
private int exponent_;
+ private final int[] bigits_ = new int[kBigitCapacity];
Bignum() {}
@@ -124,7 +121,9 @@
void assignUInt16(final char value) {
assert (kBigitSize >= 16);
zero();
- if (value == 0) return;
+ if (value == 0) {
+ return;
+ }
ensureCapacity(1);
bigits_[0] = value;
@@ -136,7 +135,9 @@
final int kUInt64Size = 64;
zero();
- if (value == 0) return;
+ if (value == 0) {
+ return;
+ }
final int needed_bigits = kUInt64Size / kBigitSize + 1;
ensureCapacity(needed_bigits);
@@ -521,26 +522,27 @@
mask >>>= 2;
long this_value = base;
- boolean delayed_multipliciation = false;
+ boolean delayed_multiplication = false;
final long max_32bits = 0xFFFFFFFFL;
while (mask != 0 && this_value <= max_32bits) {
this_value = this_value * this_value;
// Verify that there is enough space in this_value to perform the
// multiplication. The first bit_size bits must be 0.
if ((power_exponent & mask) != 0) {
+ assert bit_size > 0;
final long base_bits_mask =
~((1L << (64 - bit_size)) - 1);
final boolean high_bits_zero = (this_value & base_bits_mask) == 0;
if (high_bits_zero) {
this_value *= base;
} else {
- delayed_multipliciation = true;
+ delayed_multiplication = true;
}
}
mask >>>= 1;
}
assignUInt64(this_value);
- if (delayed_multipliciation) {
+ if (delayed_multiplication) {
multiplyByUInt32(base);
}
@@ -681,7 +683,7 @@
}
- int bigitAt(final int index) {
+ int bigitOrZero(final int index) {
if (index >= bigitLength()) return 0;
if (index < exponent_) return 0;
return bigits_[index - exponent_];
@@ -696,8 +698,8 @@
if (bigit_length_a < bigit_length_b) return -1;
if (bigit_length_a > bigit_length_b) return +1;
for (int i = bigit_length_a - 1; i >= Math.min(a.exponent_, b.exponent_); --i) {
- final int bigit_a = a.bigitAt(i);
- final int bigit_b = b.bigitAt(i);
+ final int bigit_a = a.bigitOrZero(i);
+ final int bigit_b = b.bigitOrZero(i);
if (bigit_a < bigit_b) return -1;
if (bigit_a > bigit_b) return +1;
// Otherwise they are equal up to this digit. Try the next digit.
@@ -726,9 +728,9 @@
// Starting at min_exponent all digits are == 0. So no need to compare them.
final int min_exponent = Math.min(Math.min(a.exponent_, b.exponent_), c.exponent_);
for (int i = c.bigitLength() - 1; i >= min_exponent; --i) {
- final int int_a = a.bigitAt(i);
- final int int_b = b.bigitAt(i);
- final int int_c = c.bigitAt(i);
+ final int int_a = a.bigitOrZero(i);
+ final int int_b = b.bigitOrZero(i);
+ final int int_c = c.bigitOrZero(i);
final int sum = int_a + int_b;
if (sum > int_c + borrow) {
return +1;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/FixedDtoa.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/FixedDtoa.java Mon Jul 22 11:08:27 2019 +0530
@@ -286,7 +286,8 @@
fractionals -= (long) (digit) << point;
}
// If the first bit after the point is set we have to round up.
- if (((fractionals >>> (point - 1)) & 1) == 1) {
+ assert (fractionals == 0 || point - 1 >= 0);
+ if ((fractionals != 0) && ((fractionals >>> (point - 1)) & 1) == 1) {
roundUp(buffer);
}
} else { // We need 128 bits.
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/IeeeDouble.java Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/IeeeDouble.java Mon Jul 22 11:08:27 2019 +0530
@@ -115,7 +115,7 @@
}
static double previousDouble(final long d64) {
- if (d64 == (kInfinity | kSignMask)) return -longToDouble(kInfinity);
+ if (d64 == (kInfinity | kSignMask)) return -Infinity();
if (sign(d64) < 0) {
return longToDouble(d64 + 1);
} else {
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties Tue Jul 16 17:00:00 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties Mon Jul 22 11:08:27 2019 +0530
@@ -288,7 +288,7 @@
name="--optimistic-types", \
short_name="-ot", \
desc="Use optimistic type assumptions with deoptimizing recompilation. This makes the compiler try, for any program symbol whose type cannot be proven at compile time, to type it as narrow and primitive as possible. If the runtime encounters an error because symbol type is too narrow, a wider method will be generated until steady stage is reached. While this produces as optimal Java Bytecode as possible, erroneous type guesses will lead to longer warmup. Optimistic typing is currently enabled by default, but can be disabled for faster startup performance.", \
- default=true \
+ default=false \
}
nashorn.option.parse.only = { \
--- a/test/hotspot/jtreg/ProblemList-aot.txt Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/ProblemList-aot.txt Mon Jul 22 11:08:27 2019 +0530
@@ -72,3 +72,11 @@
serviceability/sa/TestRevPtrsForInvokeDynamic.java 8216181 generic-all
serviceability/sa/TestType.java 8216181 generic-all
serviceability/sa/TestUniverse.java 8216181 generic-all
+
+compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java 8167430 generic-all
+compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java 8167430 generic-all
+compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java 8167430 generic-all
+compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java 8167430 generic-all
+compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java 8167430 generic-all
+compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java 8167430 generic-all
+
--- a/test/hotspot/jtreg/ProblemList-graal.txt Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/ProblemList-graal.txt Mon Jul 22 11:08:27 2019 +0530
@@ -38,8 +38,6 @@
compiler/compilercontrol/mixed/RandomValidCommandsTest.java 8181753 generic-all
compiler/compilercontrol/mixed/RandomCommandsTest.java 8181753 generic-all
-compiler/graalunit/HotspotJdk9Test.java 8223807 generic-all
-compiler/jsr292/InvokerSignatureMismatch.java 8223807 generic-all
compiler/graalunit/JttThreadsTest.java 8207757 generic-all
--- a/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java Mon Jul 22 11:08:27 2019 +0530
@@ -113,7 +113,7 @@
procArgs = new String[argcount];
procArgs[argcount - 4] = "-XX:+UnlockExperimentalVMOptions";
procArgs[argcount - 3] = "-XX:+UseShenandoahGC";
- procArgs[argcount - 2] = "-XX:ShenandoahGCHeuristics=traversal";
+ procArgs[argcount - 2] = "-XX:ShenandoahGCMode=traversal";
break;
default:
throw new RuntimeException("unexpected test type " + testType);
--- a/test/hotspot/jtreg/gc/CriticalNativeArgs.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/CriticalNativeArgs.java Mon Jul 22 11:08:27 2019 +0530
@@ -40,13 +40,14 @@
* @library /
* @requires (os.arch =="x86_64" | os.arch == "amd64") & vm.gc.Shenandoah & !vm.graal.enabled
* @summary test argument unpacking nmethod wrapper of critical native method
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
*
* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
*
* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -Xmx256M -XX:+CriticalJNINatives gc.CriticalNativeArgs
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=traversal -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=traversal -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
*/
public class CriticalNativeArgs {
public static void main(String[] args) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/arguments/GCArguments.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package gc.arguments;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * Helper class for adding options to child processes that should be
+ * used by all of the argument tests in this package. The default
+ * options are added at the front, to allow them to be overridden by
+ * explicit options from any particular test.
+ */
+
+public final class GCArguments {
+
+ // Avoid excessive execution time.
+ static private void disableZapUnusedHeapArea(List<String> arguments) {
+ // Develop option, only available in debug builds.
+ if (Platform.isDebugBuild()) {
+ arguments.add("-XX:-ZapUnusedHeapArea");
+ }
+ }
+
+ // Avoid excessive execution time.
+ static private void disableVerifyBeforeExit(List<String> arguments) {
+ // Diagnostic option, default enabled in debug builds.
+ if (Platform.isDebugBuild()) {
+ arguments.add("-XX:-VerifyBeforeExit");
+ }
+ }
+
+ static private void addDefaults(List<String> arguments) {
+ disableZapUnusedHeapArea(arguments);
+ disableVerifyBeforeExit(arguments);
+ }
+
+ static private String[] withDefaults(String[] arguments) {
+ List<String> augmented = new ArrayList<String>();
+ addDefaults(augmented);
+ Collections.addAll(augmented, arguments);
+ return augmented.toArray(new String[augmented.size()]);
+ }
+
+ static public ProcessBuilder createJavaProcessBuilder(String... arguments) {
+ return createJavaProcessBuilder(false, arguments);
+ }
+
+ static public ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions,
+ String... arguments) {
+ return ProcessTools.createJavaProcessBuilder(addTestVmAndJavaOptions,
+ withDefaults(arguments));
+ }
+
+}
--- a/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @requires vm.gc.Parallel
* @summary Test argument processing for -XX:+AggressiveHeap.
* @library /test/lib
+ * @library /
* @modules java.base java.management
* @run driver gc.arguments.TestAggressiveHeap
*/
@@ -66,7 +67,7 @@
" *bool +UseParallelGC *= *true +\\{product\\} *\\{command line\\}";
private static void testFlag() throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
option, heapSizeOption, "-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/test/hotspot/jtreg/gc/arguments/TestArrayAllocatorMallocLimit.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestArrayAllocatorMallocLimit.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @bug 8054823
* @key gc
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run driver gc.arguments.TestArrayAllocatorMallocLimit
@@ -52,7 +53,7 @@
private static final String printFlagsFinalPattern = " *size_t *" + flagName + " *:?= *(\\d+) *\\{experimental\\} *";
public static void testDefaultValue() throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions", "-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
@@ -78,7 +79,7 @@
public static void testSetValue() throws Exception {
long flagValue = 2048;
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions", "-XX:" + flagName + "=" + flagValue, "-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -33,6 +33,7 @@
* @summary Tests that VM prints a warning when -XX:CompressedClassSpaceSize
* is used together with -XX:-UseCompressedClassPointers
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestCompressedClassFlags
@@ -50,7 +51,7 @@
}
private static OutputAnalyzer runJava(String ... args) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(args);
return new OutputAnalyzer(pb.start());
}
}
--- a/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,7 @@
* @bug 8068579
* @key gc
* @library /test/lib
+ * @library /
* @requires vm.gc=="null"
* @modules java.base/jdk.internal.misc
* java.management
@@ -41,14 +42,14 @@
public class TestDisableDefaultGC {
public static void main(String[] args) throws Exception {
// Start VM, disabling all possible default GCs
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:-UseSerialGC",
- "-XX:-UseParallelGC",
- "-XX:-UseG1GC",
- "-XX:-UseConcMarkSweepGC",
- "-XX:+UnlockExperimentalVMOptions",
- "-XX:-UseShenandoahGC",
- "-XX:-UseZGC",
- "-version");
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder("-XX:-UseSerialGC",
+ "-XX:-UseParallelGC",
+ "-XX:-UseG1GC",
+ "-XX:-UseConcMarkSweepGC",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-UseShenandoahGC",
+ "-XX:-UseZGC",
+ "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldMatch("Garbage collector not selected");
output.shouldHaveExitValue(1);
--- a/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,7 @@
* @requires vm.gc.G1
* @summary Tests argument processing for double type flag, G1ConcMarkStepDurationMillis
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestG1ConcMarkStepDurationMillis
@@ -79,7 +80,7 @@
Collections.addAll(vmOpts, "-XX:+UseG1GC", "-XX:G1ConcMarkStepDurationMillis="+expectedValue, "-XX:+PrintFlagsFinal", "-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(expectedResult == PASS ? 0 : 1);
--- a/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @requires vm.gc.G1
* @summary Tests argument processing for G1ConcRefinementThreads
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestG1ConcRefinementThreads
@@ -70,7 +71,7 @@
}
Collections.addAll(vmOpts, "-XX:+UseG1GC", "-XX:+PrintFlagsFinal", "-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java Mon Jul 22 11:08:27 2019 +0530
@@ -32,6 +32,7 @@
* @modules java.base/jdk.internal.misc
* @modules java.management/sun.management
* @library /test/lib
+ * @library /
* @run main gc.arguments.TestG1HeapRegionSize
*/
@@ -53,7 +54,7 @@
flagList.add("-XX:+PrintFlagsFinal");
flagList.add("-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flagList.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(flagList.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(exitValue);
--- a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @requires vm.gc.G1
* @summary Test argument processing of various percentage options
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run driver gc.arguments.TestG1PercentageOptions
@@ -65,7 +66,7 @@
private static void check(String flag, boolean is_valid) throws Exception {
String[] flags = new String[] { "-XX:+UseG1GC", flag, "-version" };
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
if (is_valid) {
output.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,7 @@
* @bug 8025661
* @summary Test parsing of -Xminf and -Xmaxf
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main/othervm gc.arguments.TestHeapFreeRatio
@@ -48,7 +49,7 @@
}
private static void testMinMaxFreeRatio(String min, String max, Validation type) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
"-Xminf" + min,
"-Xmaxf" + max,
"-version");
--- a/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @requires vm.gc.Parallel
* @summary Tests argument processing for initial tenuring threshold
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main/othervm gc.arguments.TestInitialTenuringThreshold
@@ -42,7 +43,7 @@
public class TestInitialTenuringThreshold {
public static void runWithThresholds(int initial, int max, boolean shouldfail) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
"-XX:+UseParallelGC",
"-XX:InitialTenuringThreshold=" + String.valueOf(initial),
"-XX:MaxTenuringThreshold=" + String.valueOf(max),
@@ -59,7 +60,7 @@
public static void main(String args[]) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
// some value below the default value of InitialTenuringThreshold of 7
"-XX:MaxTenuringThreshold=1",
"-version"
--- a/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java Mon Jul 22 11:08:27 2019 +0530
@@ -116,7 +116,7 @@
}
private static void getNewOldSize(String gcflag, long[] values) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(gcflag,
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(gcflag,
"-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
@@ -135,7 +135,8 @@
expectError(new String[] { gcflag, "-XX:InitialHeapSize=1023K", "-version" });
expectError(new String[] { gcflag, "-Xms64M", "-XX:InitialHeapSize=32M", "-version" });
expectError(new String[] { gcflag, "-XX:MinHeapSize=1023K", "-version" });
- expectError(new String[] { gcflag, "-Xms4M", "-XX:MinHeapSize=8M", "-version" });
+ // Note: MinHeapSize values get aligned up by HeapAlignment which is 32M with 64k pages.
+ expectError(new String[] { gcflag, "-Xms4M", "-XX:MinHeapSize=64M", "-version" });
expectError(new String[] { gcflag, "-XX:MinHeapSize=8M -XX:InitialHeapSize=4m" });
}
@@ -219,7 +220,7 @@
finalargs.add(classname);
finalargs.addAll(Arrays.asList(arguments));
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(finalargs.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
@@ -319,7 +320,7 @@
}
private static void expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
shouldContainOrNot(output, hasWarning, "Warning");
shouldContainOrNot(output, hasError, "Error");
--- a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -100,7 +100,7 @@
Boolean.toString(shrinkHeapInSteps)
);
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(0);
}
@@ -125,7 +125,7 @@
"--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-version"
);
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(1);
analyzer.shouldContain("Error: Could not create the Java Virtual Machine.");
--- a/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java Mon Jul 22 11:08:27 2019 +0530
@@ -31,6 +31,7 @@
* processing.
* @requires vm.gc.Serial
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestMaxNewSize -XX:+UseSerialGC
@@ -45,6 +46,7 @@
* processing.
* @requires vm.gc.Parallel
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestMaxNewSize -XX:+UseParallelGC
@@ -59,6 +61,7 @@
* processing.
* @requires vm.gc.G1
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestMaxNewSize -XX:+UseG1GC
@@ -72,6 +75,7 @@
* @comment Graal does not support CMS
* @requires vm.gc.ConcMarkSweep & !vm.graal.enabled
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main gc.arguments.TestMaxNewSize -XX:+UseConcMarkSweepGC
@@ -104,7 +108,7 @@
finalargs.addAll(Arrays.asList(flags));
finalargs.add("-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(finalargs.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Initial young gen size set larger than the maximum young gen size");
}
@@ -127,7 +131,7 @@
finalargs.add("-XX:+PrintFlagsFinal");
finalargs.add("-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(finalargs.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
String stdout = output.getStdout();
--- a/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -64,7 +64,7 @@
args.add("-XX:+PrintFlagsFinal");
args.add("-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(args.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
String stdout = output.getStdout();
@@ -87,7 +87,7 @@
args.add("-XX:+PrintFlagsFinal");
args.add("-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(args.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
String stdout = output.getStdout();
--- a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -104,7 +104,7 @@
Boolean.toString(useAdaptiveSizePolicy)
);
vmOptions.removeIf((String p) -> p.isEmpty());
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(0);
}
--- a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java Mon Jul 22 11:08:27 2019 +0530
@@ -84,7 +84,7 @@
Integer.toString(ratio)
);
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(0);
System.out.println(analyzer.getOutput());
--- a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -168,7 +168,7 @@
Long.toString(maxHeapSize)
);
vmOptions.removeIf(String::isEmpty);
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
return analyzer;
}
--- a/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,7 @@
* @bug 8144527
* @summary Tests argument processing for NewSizeThreadIncrease
* @library /test/lib
+ * @library /
* @requires vm.gc.Serial
* @modules java.base/jdk.internal.misc
* java.management
@@ -67,13 +68,13 @@
}
static void runNewSizeThreadIncreaseTest(String expectedValue, boolean isNewsizeChanged) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseSerialGC",
- "-Xms96M",
- "-Xmx128M",
- "-XX:NewRatio=2",
- "-Xlog:gc+heap+ergo=debug",
- "-XX:NewSizeThreadIncrease="+expectedValue,
- GCTest.class.getName());
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder("-XX:+UseSerialGC",
+ "-Xms96M",
+ "-Xmx128M",
+ "-XX:NewRatio=2",
+ "-Xlog:gc+heap+ergo=debug",
+ "-XX:NewSizeThreadIncrease="+expectedValue,
+ GCTest.class.getName());
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -163,7 +163,7 @@
}
Collections.addAll(vmOpts, "-XX:+UseParallelGC", "-XX:+PrintFlagsFinal", "-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
if (shouldFail) {
--- a/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java Mon Jul 22 11:08:27 2019 +0530
@@ -58,7 +58,7 @@
private static final String printFlagsFinalPattern = " *uint *" + flagName + " *:?= *(\\d+) *\\{product\\} *";
public static void testDefaultValue() throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions", "-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
@@ -101,7 +101,7 @@
// Make sure the VM does not allow ParallelGCThreads set to 0
String[] flags = new String[] {"-XX:+Use" + gc + "GC", "-XX:ParallelGCThreads=0", "-XX:+PrintFlagsFinal", "-version"};
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(1);
@@ -124,7 +124,7 @@
}
public static long getParallelGCThreadCount(String flags[]) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
String stdout = output.getStdout();
--- a/test/hotspot/jtreg/gc/arguments/TestParallelRefProc.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestParallelRefProc.java Mon Jul 22 11:08:27 2019 +0530
@@ -28,6 +28,7 @@
* @key gc
* @summary Test defaults processing for -XX:+ParallelRefProcEnabled.
* @library /test/lib
+ * @library /
* @build sun.hotspot.WhiteBox
* @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.arguments.TestParallelRefProc
@@ -80,7 +81,7 @@
result.addAll(Arrays.asList(args));
result.add("-XX:+PrintFlagsFinal");
result.add("-version");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(result.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(result.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,7 @@
* @bug 8068582
* @key gc
* @library /test/lib
+ * @library /
* @requires vm.gc.Serial & vm.gc.G1
* @modules java.base/jdk.internal.misc
* java.management
@@ -52,7 +53,7 @@
};
// Start VM without specifying GC
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(args);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @requires vm.gc.Parallel
* @summary Check large pages and NUMA are working together via the output message.
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* @modules java.management/sun.management
* @build TestSmallInitialHeapWithLargePageAndNUMA
@@ -67,7 +68,7 @@
"-XX:+PrintFlagsFinal",
"-version"};
- ProcessBuilder pb_enabled = ProcessTools.createJavaProcessBuilder(vmArgs);
+ ProcessBuilder pb_enabled = GCArguments.createJavaProcessBuilder(vmArgs);
OutputAnalyzer analyzer = new OutputAnalyzer(pb_enabled.start());
if (largePageOrNumaEnabled(analyzer)) {
--- a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java Mon Jul 22 11:08:27 2019 +0530
@@ -35,8 +35,9 @@
import jdk.test.lib.process.ProcessTools;
public class TestSoftMaxHeapSizeFlag {
- private static final long Xms = 200 * 1024 * 1024;
- private static final long Xmx = 300 * 1024 * 1024;
+ // Note: Xms and Xmx values get aligned up by HeapAlignment which is 32M with 64k pages.
+ private static final long Xms = 224 * 1024 * 1024;
+ private static final long Xmx = 320 * 1024 * 1024;
private static final long greaterThanXmx = Xmx + 1;
private static final long betweenXmsAndXmx = (Xms + Xmx) / 2;
--- a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java Mon Jul 22 11:08:27 2019 +0530
@@ -89,7 +89,7 @@
Integer.toString(ratio)
);
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(0);
}
--- a/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java Mon Jul 22 11:08:27 2019 +0530
@@ -119,7 +119,7 @@
vmOptions.add("-XX:TargetSurvivorRatio=" + ratio);
vmOptions.add("-version");
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(1);
@@ -154,7 +154,7 @@
Integer.toString(ratio)
);
- ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+ ProcessBuilder procBuilder = GCArguments.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,7 @@
* @bug 8017611
* @summary Tests handling unrecognized VM options
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run main/othervm gc.arguments.TestUnrecognizedVMOptionsHandling
@@ -41,7 +42,7 @@
public static void main(String args[]) throws Exception {
// The first two JAVA processes are expected to fail, but with a correct VM option suggestion
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
"-XX:+UseDynamicNumberOfGcThreads",
"-version"
);
@@ -51,7 +52,7 @@
throw new RuntimeException("Not expected to get exit value 0");
}
- pb = ProcessTools.createJavaProcessBuilder(
+ pb = GCArguments.createJavaProcessBuilder(
"-XX:MaxiumHeapSize=500m",
"-version"
);
@@ -62,7 +63,7 @@
}
// The last JAVA process should run successfully for the purpose of sanity check
- pb = ProcessTools.createJavaProcessBuilder(
+ pb = GCArguments.createJavaProcessBuilder(
"-XX:+UseDynamicNumberOfGCThreads",
"-version"
);
--- a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java Mon Jul 22 11:08:27 2019 +0530
@@ -105,7 +105,7 @@
finalargs.add(classname);
finalargs.addAll(Arrays.asList(arguments));
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(finalargs.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
return output;
@@ -169,7 +169,7 @@
}
private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(errorcode);
return output.getStdout();
--- a/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,6 +30,7 @@
* @bug 8059614
* @key gc
* @library /test/lib
+ * @library /
* @modules java.base/jdk.internal.misc
* java.management
* @run driver gc.arguments.TestUseNUMAInterleaving
@@ -45,7 +46,7 @@
"-XX:+PrintFlagsFinal",
"-version"
};
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, vmargs);
+ ProcessBuilder pb = GCArguments.createJavaProcessBuilder(true, vmargs);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
boolean isNUMAEnabled
--- a/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -34,6 +34,7 @@
* @modules java.base/jdk.internal.misc
* @modules java.management
* @library /test/lib
+ * @library /
* @run driver gc.arguments.TestVerifyBeforeAndAfterGCFlags
*/
@@ -76,7 +77,6 @@
if (opts != null && (opts.length > 0)) {
Collections.addAll(vmOpts, opts);
}
-
Collections.addAll(vmOpts, new String[] {
"-Xlog:gc+verify=debug",
"-Xmx5m",
@@ -89,8 +89,8 @@
: "-XX:-VerifyAfterGC"),
GarbageProducer.class.getName() });
ProcessBuilder procBuilder =
- ProcessTools.createJavaProcessBuilder(vmOpts.toArray(
- new String[vmOpts.size()]));
+ GCArguments.createJavaProcessBuilder(vmOpts.toArray(
+ new String[vmOpts.size()]));
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
analyzer.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Mon Jul 22 11:08:27 2019 +0530
@@ -97,6 +97,8 @@
// Merge Heap Roots
new LogMessageWithLevel("Merge Heap Roots", Level.INFO),
+ new LogMessageWithLevel("Prepare Merge Heap Roots", Level.DEBUG),
+ new LogMessageWithLevel("Eager Reclaim", Level.DEBUG),
new LogMessageWithLevel("Remembered Sets", Level.DEBUG),
new LogMessageWithLevel("Merged Sparse", Level.DEBUG),
new LogMessageWithLevel("Merged Fine", Level.DEBUG),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Twitter, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.metaspace;
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/* @test TestSizeTransitionsSerial
+ * @key gc
+ * @requires vm.gc.Serial
+ * @summary Tests that the metaspace size transition logging is done correctly.
+ * @library /test/lib
+ * @run driver gc.metaspace.TestSizeTransitions false -XX:+UseSerialGC
+ * @run driver gc.metaspace.TestSizeTransitions true -XX:+UseSerialGC
+ */
+
+/* @test TestSizeTransitionsParallel
+ * @key gc
+ * @requires vm.gc.Parallel
+ * @summary Tests that the metaspace size transition logging is done correctly.
+ * @library /test/lib
+ * @run driver gc.metaspace.TestSizeTransitions false -XX:+UseParallelGC
+ * @run driver gc.metaspace.TestSizeTransitions true -XX:+UseParallelGC
+ */
+
+/* @test TestSizeTransitionsG1
+ * @key gc
+ * @requires vm.gc.G1
+ * @summary Tests that the metaspace size transition logging is done correctly.
+ * @library /test/lib
+ * @run driver gc.metaspace.TestSizeTransitions false -XX:+UseG1GC
+ * @run driver gc.metaspace.TestSizeTransitions true -XX:+UseG1GC
+ */
+
+/* @test TestSizeTransitionsCMS
+ * @key gc
+ * @requires vm.gc.ConcMarkSweep
+ * @summary Tests that the metaspace size transition logging is done correctly.
+ * @library /test/lib
+ * @run driver gc.metaspace.TestSizeTransitions false -XX:+UseConcMarkSweepGC
+ * @run driver gc.metaspace.TestSizeTransitions true -XX:+UseConcMarkSweepGC
+ */
+
+public class TestSizeTransitions {
+ public static class Run {
+ public static void main(String... args) throws Exception {
+ System.out.println("Run started.");
+
+ // easiest way to generate a metaspace transition is to ask for a full GC
+ System.gc();
+
+ System.out.println("Run finished.");
+ }
+ }
+
+ // matches the log tags
+ // e.g., [0.043s][info][gc]
+ private static final String LOG_TAGS_REGEX = "(\\[.*\\])+ ";
+
+ // matches a size transition
+ // e.g., 177K(4864K)->177K(4864K)
+ private static final String SIZE_TRANSITION_REGEX = "\\d+K\\(\\d+K\\)->\\d+K\\(\\d+K\\)";
+
+ // matches -coops metaspace size transitions
+ private static final String NO_COOPS_REGEX =
+ String.format("^%s.* Metaspace: %s$",
+ LOG_TAGS_REGEX,
+ SIZE_TRANSITION_REGEX);
+
+ // matches +coops metaspace size transitions
+ private static final String COOPS_REGEX =
+ String.format("^%s.* Metaspace: %s NonClass: %s Class: %s$",
+ LOG_TAGS_REGEX,
+ SIZE_TRANSITION_REGEX,
+ SIZE_TRANSITION_REGEX,
+ SIZE_TRANSITION_REGEX);
+
+ public static void main(String... args) throws Exception {
+ // args: <use-coops> <gc-arg>
+ if (args.length != 2) {
+ throw new RuntimeException("wrong number of args: " + args.length);
+ }
+
+ final boolean useCoops = Boolean.parseBoolean(args[0]);
+ final String gcArg = args[1];
+ final String[] jvmArgs = {
+ useCoops ? "-XX:+UseCompressedOops" : "-XX:-UseCompressedOops",
+ gcArg,
+ "-Xmx256m",
+ "-Xlog:gc,gc+metaspace=info",
+ TestSizeTransitions.Run.class.getName()
+ };
+
+ System.out.println("JVM args:");
+ for (String a : jvmArgs) {
+ System.out.println(" " + a);
+ }
+
+ final ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(jvmArgs);
+ final OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ System.out.println(output.getStdout());
+ output.shouldHaveExitValue(0);
+
+ if (useCoops) {
+ output.stdoutShouldMatch(COOPS_REGEX);
+ output.stdoutShouldNotMatch(NO_COOPS_REGEX);
+ } else {
+ output.stdoutShouldMatch(NO_COOPS_REGEX);
+ output.stdoutShouldNotMatch(COOPS_REGEX);
+ }
+ }
+}
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocHumongousFragment.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocHumongousFragment.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,22 +27,105 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocHumongousFragment
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestAllocHumongousFragment
+ */
+
+/*
+ * @test TestAllocHumongousFragment
+ * @summary Make sure Shenandoah can recover from humongous allocation fragmentation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocHumongousFragment
*
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocHumongousFragment
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xmx1g -Xms1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestAllocHumongousFragment
+ */
+
+/*
+ * @test TestAllocHumongousFragment
+ * @summary Make sure Shenandoah can recover from humongous allocation fragmentation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestAllocHumongousFragment
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
*
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=adaptive TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=static TestAllocHumongousFragment
- * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 -XX:ShenandoahGCHeuristics=traversal TestAllocHumongousFragment
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestAllocHumongousFragment
*/
import java.util.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocIntArrays.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocIntArrays.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,26 +27,118 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocIntArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestAllocIntArrays
+ */
+
+/*
+ * @test TestAllocIntArrays
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestAllocIntArrays
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive TestAllocIntArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ */
+
+/*
+ * @test TestAllocIntArrays
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestAllocIntArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocIntArrays
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocIntArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocIntArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestAllocIntArrays
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestAllocIntArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestAllocIntArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestAllocIntArrays
*/
import java.util.Random;
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocObjectArrays.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocObjectArrays.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,26 +27,117 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocObjectArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestAllocObjectArrays
+
+/*
+ * @test TestAllocObjectArrays
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive TestAllocObjectArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ */
+
+/*
+ * @test TestAllocObjectArrays
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestAllocObjectArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocObjectArrays
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocObjectArrays
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestAllocObjectArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestAllocObjectArrays
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestAllocObjectArrays
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestAllocObjectArrays
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestAllocObjectArrays
*/
import java.util.Random;
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,30 +27,138 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestAllocObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestAllocObjects
+ */
+
+/*
+ * @test TestAllocObjects
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive TestAllocObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahSuspendibleWorkers
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestAllocObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestAllocObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahSuspendibleWorkers
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * -XX:+ShenandoahSuspendibleWorkers
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -XX:+ShenandoahSuspendibleWorkers
+ * TestAllocObjects
+ */
+
+/*
+ * @test TestAllocObjects
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestAllocObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestAllocObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestAllocObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahSuspendibleWorkers
+ * TestAllocObjects
*/
import java.util.Random;
--- a/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,21 +27,121 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:-UseDynamicNumberOfGCThreads -Xmx16m -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UnlockDiagnosticVMOptions -XX:+ForceDynamicNumberOfGCThreads -Xmx16m -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -XX:ShenandoahGCHeuristics=adaptive -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -XX:ShenandoahGCHeuristics=static -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -XX:ShenandoahGCHeuristics=compact -Dtarget=100 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=100 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 -Xmx16m -XX:ShenandoahGCHeuristics=traversal -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -Xmx16m -XX:ShenandoahGCHeuristics=adaptive -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -Xmx16m -XX:ShenandoahGCHeuristics=static -Dtarget=1000 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -Xmx16m -XX:ShenandoahGCHeuristics=compact -Dtarget=100 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=100 TestGCThreadGroups
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2 -Xmx16m -XX:ShenandoahGCHeuristics=traversal -Dtarget=1000 TestGCThreadGroups
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ */
+
+/**
+ * @test TestGCThreadGroups
+ * @summary Test Shenandoah GC uses concurrent/parallel threads correctly
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:-UseDynamicNumberOfGCThreads
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:+ForceDynamicNumberOfGCThreads
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=100
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=100
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=100
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=100
+ * TestGCThreadGroups
+ */
+
+/**
+ * @test TestGCThreadGroups
+ * @summary Test Shenandoah GC uses concurrent/parallel threads correctly
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=1000
+ * TestGCThreadGroups
+ *
+ * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
+ * -Dtarget=1000
+ * TestGCThreadGroups
*/
public class TestGCThreadGroups {
--- a/test/hotspot/jtreg/gc/shenandoah/TestHeapUncommit.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestHeapUncommit.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,34 +27,98 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestHeapUncommit
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestHeapUncommit
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:+ShenandoahVerify TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=static -XX:+ShenandoahVerify TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestHeapUncommit
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestHeapUncommit
+ */
+
+/*
+ * @test TestHeapUncommit
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestHeapUncommit
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:-UseTLAB -XX:+ShenandoahVerify TestHeapUncommit
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestHeapUncommit
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 TestHeapUncommit
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestHeapUncommit
+ */
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=adaptive TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=static TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=compact TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=aggressive TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:ShenandoahGCHeuristics=traversal TestHeapUncommit
+/*
+ * @test TestHeapUncommit
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestHeapUncommit
*/
/*
* @test TestHeapUncommit
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled & (vm.bits == "64")
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:+UseLargePages -XX:+ShenandoahVerify TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:+UseLargePages TestHeapUncommit
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:-UseTLAB -XX:+UseLargePages -XX:+ShenandoahVerify TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:+UseLargePages
+ * -XX:+UseShenandoahGC
+ * -XX:+ShenandoahVerify
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:+UseLargePages
+ * -XX:+UseShenandoahGC
+ * TestHeapUncommit
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 -XX:+UseLargePages
+ * -XX:+UseShenandoahGC
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestHeapUncommit
*/
import java.util.Random;
--- a/test/hotspot/jtreg/gc/shenandoah/TestLotsOfCycles.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestLotsOfCycles.java Mon Jul 22 11:08:27 2019 +0530
@@ -26,18 +26,83 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=10000 -XX:+ShenandoahDegeneratedGC TestLotsOfCycles
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=passive -Dtarget=10000 -XX:-ShenandoahDegeneratedGC TestLotsOfCycles
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * -Dtarget=10000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * -Dtarget=10000
+ * TestLotsOfCycles
+ */
+
+/*
+ * @test TestLotsOfCycles
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * -Dtarget=1000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * -Dtarget=1000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -Dtarget=1000
+ * TestLotsOfCycles
*
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=1000 -XX:+ShenandoahOOMDuringEvacALot TestLotsOfCycles
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=1000 -XX:+ShenandoahAllocFailureALot TestLotsOfCycles
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=aggressive -Dtarget=1000 TestLotsOfCycles
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -Dtarget=10000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * -Dtarget=10000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -Dtarget=1000
+ * TestLotsOfCycles
+ */
+
+/*
+ * @test TestLotsOfCycles
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=adaptive -Dtarget=10000 TestLotsOfCycles
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=traversal -Dtarget=10000 TestLotsOfCycles
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * -Dtarget=1000
+ * TestLotsOfCycles
*
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=static -Dtarget=10000 TestLotsOfCycles
- * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx16m -XX:ShenandoahGCHeuristics=compact -Dtarget=1000 TestLotsOfCycles
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * -Dtarget=1000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -Dtarget=1000
+ * TestLotsOfCycles
+ *
+ * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -Dtarget=10000
+ * TestLotsOfCycles
*/
public class TestLotsOfCycles {
--- a/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java Mon Jul 22 11:08:27 2019 +0530
@@ -55,25 +55,27 @@
System.exit(0);
}
- String[] heuristics = new String[] {
- "adaptive",
- "compact",
- "static",
- "aggressive",
- "passive",
- "traversal",
+ String[][][] modeHeuristics = new String[][][] {
+ {{"normal"}, {"adaptive", "compact", "static", "aggressive"}},
+ {{"traversal"}, {"adaptive", "aggressive"}},
+ {{"passive"}, {"passive"}}
};
- for (String h : heuristics) {
- testWith("-XX:+UnlockDiagnosticVMOptions",
- "-XX:+UnlockExperimentalVMOptions",
- "-XX:+UseShenandoahGC",
- "-XX:-ShenandoahDegeneratedGC",
- "-XX:ShenandoahGCHeuristics=" + h,
- "-Xlog:gc+classhisto=trace",
- "-XX:-ExplicitGCInvokesConcurrent",
- "-Xmx512M"
- );
+ for (String[][] mh : modeHeuristics) {
+ String mode = mh[0][0];
+ String[] heuristics = mh[1];
+ for (String h : heuristics) {
+ testWith("-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:-ShenandoahDegeneratedGC",
+ "-XX:ShenandoahGCMode=" + mode,
+ "-XX:ShenandoahGCHeuristics=" + h,
+ "-Xlog:gc+classhisto=trace",
+ "-XX:-ExplicitGCInvokesConcurrent",
+ "-Xmx512M"
+ );
+ }
}
}
}
--- a/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java Mon Jul 22 11:08:27 2019 +0530
@@ -64,12 +64,6 @@
"adaptive",
"compact",
"static",
- "traversal",
- };
-
- String[] disabled = new String[] {
- "aggressive",
- "passive",
};
for (String h : enabled) {
@@ -94,17 +88,44 @@
);
}
- for (String h : disabled) {
- testWith("Short period with " + h,
- false,
- "-Xlog:gc",
- "-XX:+UnlockDiagnosticVMOptions",
- "-XX:+UnlockExperimentalVMOptions",
- "-XX:+UseShenandoahGC",
- "-XX:ShenandoahGCHeuristics=" + h,
- "-XX:ShenandoahGuaranteedGCInterval=1000"
- );
- }
+ testWith("Short period with traversal mode",
+ true,
+ "-Xlog:gc",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:ShenandoahGCMode=traversal",
+ "-XX:ShenandoahGuaranteedGCInterval=1000"
+ );
+
+ testWith("Long period with traversal mode",
+ false,
+ "-Xlog:gc",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:ShenandoahGCMode=traversal",
+ "-XX:ShenandoahGuaranteedGCInterval=100000" // deliberately too long
+ );
+
+ testWith("Short period with aggressive",
+ false,
+ "-Xlog:gc",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:ShenandoahGCHeuristics=aggressive",
+ "-XX:ShenandoahGuaranteedGCInterval=1000"
+ );
+ testWith("Short period with passive",
+ false,
+ "-Xlog:gc",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:ShenandoahGCMode=passive",
+ "-XX:ShenandoahGuaranteedGCInterval=1000"
+ );
}
}
--- a/test/hotspot/jtreg/gc/shenandoah/TestRefprocSanity.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestRefprocSanity.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,11 +27,38 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g TestRefprocSanity
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:+ShenandoahVerify TestRefprocSanity
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive TestRefprocSanity
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:+ShenandoahVerify -XX:ShenandoahGCHeuristics=traversal TestRefprocSanity
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestRefprocSanity
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:+ShenandoahVerify
+ * TestRefprocSanity
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * TestRefprocSanity
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestRefprocSanity
+ */
+
+/*
+ * @test TestRefprocSanity
+ * @summary Test that null references/referents work fine
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestRefprocSanity
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestRefprocSanity
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestRefprocSanity
*/
import java.lang.ref.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestRegionSampling.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestRegionSampling.java Mon Jul 22 11:08:27 2019 +0530
@@ -25,16 +25,50 @@
* @test TestRegionSampling
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahRegionSampling TestRegionSampling
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestRegionSampling
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestRegionSampling
+ */
+
+/*
+ * @test TestRegionSampling
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestRegionSampling
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahRegionSampling TestRegionSampling
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahRegionSampling TestRegionSampling
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestRegionSampling
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestRegionSampling
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestRegionSampling
+ */
+
+/*
+ * @test TestRegionSampling
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestRegionSampling
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestRegionSampling
+ *
*/
public class TestRegionSampling {
--- a/test/hotspot/jtreg/gc/shenandoah/TestRetainObjects.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestRetainObjects.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,24 +27,98 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestRetainObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestRetainObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive TestRetainObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestRetainObjects
+ */
+
+/*
+ * @test TestRetainObjects
+ * @summary Acceptance tests: collector can deal with retained objects
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestRetainObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestRetainObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestRetainObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestRetainObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestRetainObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestRetainObjects
+ */
+
+/*
+ * @test TestRetainObjects
+ * @summary Acceptance tests: collector can deal with retained objects
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestRetainObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestRetainObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestRetainObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestRetainObjects
*/
public class TestRetainObjects {
--- a/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,24 +27,98 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestSieveObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestSieveObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive TestSieveObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestSieveObjects
+ */
+
+/*
+ * @test TestSieveObjects
+ * @summary Acceptance tests: collector can deal with retained objects
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestSieveObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestSieveObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestSieveObjects
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestSieveObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestSieveObjects
+ * @run main/othervm/timeout=240 -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestSieveObjects
+ */
+
+/*
+ * @test TestSieveObjects
+ * @summary Acceptance tests: collector can deal with retained objects
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * TestSieveObjects
*
- * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:-UseTLAB -XX:+ShenandoahVerify TestSieveObjects
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestSieveObjects
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestSieveObjects
*/
import java.util.concurrent.ThreadLocalRandom;
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringDedup.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringDedup.java Mon Jul 22 11:08:27 2019 +0530
@@ -21,7 +21,28 @@
*
*/
- /*
+/*
+ * @test TestStringDedup
+ * @summary Test Shenandoah string deduplication implementation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc:open
+ * @modules java.base/java.lang:open
+ * java.management
+ *
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestStringDedup
+ *
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestStringDedup
+ */
+
+/*
* @test TestStringDedup
* @summary Test Shenandoah string deduplication implementation
* @key gc
@@ -30,15 +51,37 @@
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+UseStringDeduplication -Xmx256M -Xlog:gc+stats TestStringDedup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+UseStringDeduplication -Xmx256M -Xlog:gc+stats TestStringDedup
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+UseStringDeduplication -Xmx256M -Xlog:gc+stats TestStringDedup
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestStringDedup
+ *
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC
+ * TestStringDedup
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx256M -Xlog:gc+stats TestStringDedup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal -XX:+UseStringDeduplication -Xmx256M -Xlog:gc+stats TestStringDedup
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestStringDedup
+ */
+
+/*
+ * @test TestStringDedup
+ * @summary Test Shenandoah string deduplication implementation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc:open
+ * @modules java.base/java.lang:open
+ * java.management
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact -XX:+UseStringDeduplication -Xmx256M -Xlog:gc+stats TestStringDedup
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestStringDedup
+ *
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestStringDedup
*/
import java.lang.reflect.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java Mon Jul 22 11:08:27 2019 +0530
@@ -21,6 +21,82 @@
*
*/
+/*
+ * @test TestStringDedupStress
+ * @summary Test Shenandoah string deduplication implementation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc:open
+ * @modules java.base/java.lang:open
+ * java.management
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestStringDedupStress
+ */
+
+/*
+ * @test TestStringDedupStress
+ * @summary Test Shenandoah string deduplication implementation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc:open
+ * @modules java.base/java.lang:open
+ * java.management
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC
+ * -DtargetStrings=3000000
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC
+ * -XX:ShenandoahUpdateRefsEarly=off
+ * -DtargetStrings=3000000
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -XX:ShenandoahUpdateRefsEarly=off
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:ShenandoahUpdateRefsEarly=off
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:ShenandoahUpdateRefsEarly=off -XX:+ShenandoahOOMDuringEvacALot
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
+ */
+
/*
* @test TestStringDedupStress
* @summary Test Shenandoah string deduplication implementation
@@ -30,75 +106,27 @@
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -DtargetStrings=3000000
- * -Xlog:gc
- * TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=aggressive -DtargetStrings=2000000
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000
- * -Xlog:gc
- * TestStringDedupStress
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=static -DtargetStrings=4000000
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=compact
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC
- * -Xlog:gc
- * TestStringDedupStress
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=traversal
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahUpdateRefsEarly=off -DtargetStrings=3000000
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=compact -XX:ShenandoahUpdateRefsEarly=off -DtargetStrings=2000000
- * -Xlog:gc
- * TestStringDedupStress
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUpdateRefsEarly=off -DtargetStrings=2000000
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=static -XX:ShenandoahUpdateRefsEarly=off
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUpdateRefsEarly=off -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000
- * -Xlog:gc
- * TestStringDedupStress
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000
- * -Xlog:gc
- * TestStringDedupStress
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * -DtargetStrings=2000000
+ * TestStringDedupStress
*/
import java.lang.management.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringInternCleanup.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringInternCleanup.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,22 +27,74 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestStringInternCleanup
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestStringInternCleanup
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestStringInternCleanup
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestStringInternCleanup
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=aggressive TestStringInternCleanup
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestStringInternCleanup
+ */
+
+/*
+ * @test TestStringInternCleanup
+ * @summary Check that Shenandoah cleans up interned strings
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestStringInternCleanup
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify TestStringInternCleanup
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * TestStringInternCleanup
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestStringInternCleanup
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestStringInternCleanup
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=adaptive TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=static TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=compact TestStringInternCleanup
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+ClassUnloadingWithConcurrentMark -Xmx64m -XX:ShenandoahGCHeuristics=traversal TestStringInternCleanup
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:-ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC
+ * TestStringInternCleanup
+ */
+
+/*
+ * @test TestStringInternCleanup
+ * @summary Check that Shenandoah cleans up interned strings
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:-ClassUnloadingWithConcurrentMark -Xmx64m TestStringInternCleanup
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * TestStringInternCleanup
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahVerify
+ * TestStringInternCleanup
+ *
+ * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestStringInternCleanup
*/
public class TestStringInternCleanup {
--- a/test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java Mon Jul 22 11:08:27 2019 +0530
@@ -28,35 +28,49 @@
* @requires vm.gc.Shenandoah & !vm.graal.enabled
* @modules java.base/jdk.internal.misc
* java.management
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
- * -XX:+UseShenandoahGC -Xmx1g -Xms1g
- * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
- * -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC
- * TestVerifyJCStress
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
+ * TestVerifyJCStress
*
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
- * -XX:+UseShenandoahGC -Xmx1g -Xms1g
- * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
- * -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC
- * TestVerifyJCStress
+ * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
+ * TestVerifyJCStress
+ */
+
+/*
+ * @test TestVerifyJCStress
+ * @summary Tests that we pass at least one jcstress-like test with all verification turned on
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @modules java.base/jdk.internal.misc
+ * java.management
*
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
- * -XX:+UseShenandoahGC -Xmx1g -Xms1g
- * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
- * -XX:ShenandoahGCHeuristics=adaptive
- * TestVerifyJCStress
+ * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
+ * TestVerifyJCStress
*
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
- * -XX:+UseShenandoahGC -Xmx1g -Xms1g
- * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
- * -XX:ShenandoahGCHeuristics=static
- * TestVerifyJCStress
+ * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
+ * TestVerifyJCStress
+ */
+
+/*
+ * @test TestVerifyJCStress
+ * @summary Tests that we pass at least one jcstress-like test with all verification turned on
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @modules java.base/jdk.internal.misc
+ * java.management
*
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
- * -XX:+UseShenandoahGC -Xmx1g -Xms1g
- * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
- * -XX:ShenandoahGCHeuristics=traversal
- * TestVerifyJCStress
+ * @run main/othervm -Xmx1g -Xms1g -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
+ * TestVerifyJCStress
*/
import java.util.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestWrongArrayMember.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestWrongArrayMember.java Mon Jul 22 11:08:27 2019 +0530
@@ -26,8 +26,8 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestWrongArrayMember
- * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal TestWrongArrayMember
+ * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestWrongArrayMember
+ * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal TestWrongArrayMember
*/
public class TestWrongArrayMember {
--- a/test/hotspot/jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java Mon Jul 22 11:08:27 2019 +0530
@@ -25,8 +25,21 @@
* @summary Test JNI Global Refs with Shenandoah
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xlog:gc -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahVerify TestJNIGlobalRefs
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xlog:gc -XX:ShenandoahGCHeuristics=aggressive TestJNIGlobalRefs
+ *
+ * @run main/othervm/native -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahVerify
+ * TestJNIGlobalRefs
+ */
+
+/* @test TestJNIGlobalRefs
+ * @summary Test JNI Global Refs with Shenandoah
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm/native -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestJNIGlobalRefs
*/
import java.util.Arrays;
--- a/test/hotspot/jtreg/gc/shenandoah/jni/TestPinnedGarbage.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/jni/TestPinnedGarbage.java Mon Jul 22 11:08:27 2019 +0530
@@ -26,12 +26,30 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx512m -XX:+ShenandoahVerify -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestPinnedGarbage
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx512m -XX:+ShenandoahVerify -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestPinnedGarbage
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahVerify -XX:+ShenandoahDegeneratedGC
+ * TestPinnedGarbage
*
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx512m -XX:ShenandoahGCHeuristics=aggressive TestPinnedGarbage
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahVerify -XX:-ShenandoahDegeneratedGC
+ * TestPinnedGarbage
+ */
+
+/* @test TestPinnedGarbage
+ * @summary Test that garbage in the pinned region does not crash VM
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx512m -XX:+ShenandoahVerify TestPinnedGarbage
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestPinnedGarbage
+ *
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m
+ * -XX:+UseShenandoahGC
+ * -XX:+ShenandoahVerify
+ * TestPinnedGarbage
*/
import java.util.Arrays;
--- a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java Mon Jul 22 11:08:27 2019 +0530
@@ -26,15 +26,57 @@
* @summary Check that MX notifications are reported for all cycles
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -Dprecise=true TestChurnNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -Dprecise=true TestChurnNotifications
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -Dprecise=true
+ * TestChurnNotifications
*
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -Dprecise=false TestChurnNotifications
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -Dprecise=true
+ * TestChurnNotifications
+ */
+
+/*
+ * @test TestChurnNotifications
+ * @summary Check that MX notifications are reported for all cycles
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -Dprecise=false
+ * TestChurnNotifications
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -Dprecise=false
+ * TestChurnNotifications
*
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive -Dprecise=false TestChurnNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static -Dprecise=false TestChurnNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact -Dprecise=false TestChurnNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal -Dprecise=false TestChurnNotifications
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * -Dprecise=false
+ * TestChurnNotifications
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * -Dprecise=false
+ * TestChurnNotifications
+ */
+
+/*
+ * @test TestChurnNotifications
+ * @summary Check that MX notifications are reported for all cycles
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -Dprecise=false
+ * TestChurnNotifications
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -Dprecise=false
+ * TestChurnNotifications
*/
import java.util.*;
--- a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,15 +27,53 @@
* @key gc
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC TestPauseNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC TestPauseNotifications
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * TestPauseNotifications
*
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive TestPauseNotifications
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * TestPauseNotifications
+ */
+
+/*
+ * @test TestPauseNotifications
+ * @summary Check that MX notifications are reported for all cycles
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * TestPauseNotifications
*
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive TestPauseNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static TestPauseNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact TestPauseNotifications
- * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal TestPauseNotifications
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * TestPauseNotifications
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
+ * TestPauseNotifications
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * TestPauseNotifications
+ */
+
+/*
+ * @test TestPauseNotifications
+ * @summary Check that MX notifications are reported for all cycles
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * TestPauseNotifications
+ *
+ * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * TestPauseNotifications
*/
import java.util.*;
--- a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java Mon Jul 22 11:08:27 2019 +0530
@@ -124,30 +124,31 @@
return;
}
- String[] heuristics = new String[] {
- "adaptive",
- "compact",
- "static",
- "traversal",
- "aggressive",
- "passive",
+ String[][][] modeHeuristics = new String[][][] {
+ {{"normal"}, {"adaptive", "compact", "static", "aggressive"}},
+ {{"traversal"}, {"adaptive", "aggressive"}},
+ {{"passive"}, {"passive"}}
};
- for (String h : heuristics) {
- // Forceful enabling should work
- passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading");
- passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloadingWithConcurrentMark");
+ for (String[][] mh : modeHeuristics) {
+ String mode = mh[0][0];
+ String[] heuristics = mh[1];
+ for (String h : heuristics) {
+ // Forceful enabling should work
+ passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading");
+ passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloadingWithConcurrentMark");
- // Even when concurrent unloading is disabled, Full GC has to recover
- passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark");
- passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0");
- passWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0");
+ // Even when concurrent unloading is disabled, Full GC has to recover
+ passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark");
+ passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0");
+ passWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:+ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=0");
- // Should OOME when unloading forcefully disabled, even if local flags try to enable it back
- failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading");
- failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark");
- failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1");
- failWith("-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1");
+ // Should OOME when unloading forcefully disabled, even if local flags try to enable it back
+ failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading");
+ failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark");
+ failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:+ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1");
+ failWith("-XX:ShenandoahGCMode=" + mode, "-XX:ShenandoahGCHeuristics=" + h, "-XX:-ClassUnloading", "-XX:-ClassUnloadingWithConcurrentMark", "-XX:ShenandoahUnloadClassesFrequency=1");
+ }
}
}
}
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java Mon Jul 22 11:08:27 2019 +0530
@@ -129,7 +129,7 @@
"-XX:+UseShenandoahGC",
"-Xlog:gc",
"-XX:+ExplicitGCInvokesConcurrent",
- "-XX:ShenandoahGCHeuristics=traversal",
+ "-XX:ShenandoahGCMode=traversal",
TestExplicitGC.class.getName(),
"test");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java Mon Jul 22 11:08:27 2019 +0530
@@ -44,14 +44,14 @@
}
public static void main(String[] args) throws Exception {
- testWith("adaptive", Mode.PRODUCT);
- testWith("static", Mode.PRODUCT);
- testWith("compact", Mode.PRODUCT);
+ testWith("-XX:ShenandoahGCHeuristics=adaptive", Mode.PRODUCT);
+ testWith("-XX:ShenandoahGCHeuristics=static", Mode.PRODUCT);
+ testWith("-XX:ShenandoahGCHeuristics=compact", Mode.PRODUCT);
- testWith("traversal", Mode.EXPERIMENTAL);
+ testWith("-XX:ShenandoahGCMode=traversal", Mode.EXPERIMENTAL);
- testWith("aggressive", Mode.DIAGNOSTIC);
- testWith("passive", Mode.DIAGNOSTIC);
+ testWith("-XX:ShenandoahGCHeuristics=aggressive", Mode.DIAGNOSTIC);
+ testWith("-XX:ShenandoahGCHeuristics=passive", Mode.DIAGNOSTIC);
}
private static void testWith(String h, Mode mode) throws Exception {
@@ -60,7 +60,7 @@
"-XX:-UnlockDiagnosticVMOptions",
"-XX:-UnlockExperimentalVMOptions",
"-XX:+UseShenandoahGC",
- "-XX:ShenandoahGCHeuristics=" + h,
+ h,
"-version"
);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
@@ -80,7 +80,7 @@
"-XX:+UnlockDiagnosticVMOptions",
"-XX:-UnlockExperimentalVMOptions",
"-XX:+UseShenandoahGC",
- "-XX:ShenandoahGCHeuristics=" + h,
+ h,
"-version"
);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
@@ -100,7 +100,7 @@
"-XX:-UnlockDiagnosticVMOptions",
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UseShenandoahGC",
- "-XX:ShenandoahGCHeuristics=" + h,
+ h,
"-version"
);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java Mon Jul 22 11:08:27 2019 +0530
@@ -65,7 +65,7 @@
conf.add("-XX:+UnlockDiagnosticVMOptions");
conf.add("-XX:+UnlockExperimentalVMOptions");
conf.add("-XX:+UseShenandoahGC");
- conf.add("-XX:ShenandoahGCHeuristics=passive");
+ conf.add("-XX:ShenandoahGCMode=passive");
StringBuilder sb = new StringBuilder();
for (String[] l : opts) {
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java Mon Jul 22 11:08:27 2019 +0530
@@ -51,13 +51,13 @@
"ShenandoahCloneBarrier",
};
- shouldFailAll("adaptive", concurrent);
- shouldFailAll("static", concurrent);
- shouldFailAll("compact", concurrent);
- shouldFailAll("aggressive", concurrent);
- shouldFailAll("traversal", traversal);
- shouldPassAll("passive", concurrent);
- shouldPassAll("passive", traversal);
+ shouldFailAll("-XX:ShenandoahGCHeuristics=adaptive", concurrent);
+ shouldFailAll("-XX:ShenandoahGCHeuristics=static", concurrent);
+ shouldFailAll("-XX:ShenandoahGCHeuristics=compact", concurrent);
+ shouldFailAll("-XX:ShenandoahGCHeuristics=aggressive", concurrent);
+ shouldFailAll("-XX:ShenandoahGCMode=traversal", traversal);
+ shouldPassAll("-XX:ShenandoahGCMode=passive", concurrent);
+ shouldPassAll("-XX:ShenandoahGCMode=passive", traversal);
}
private static void shouldFailAll(String h, String[] barriers) throws Exception {
@@ -66,7 +66,7 @@
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UseShenandoahGC",
- "-XX:ShenandoahGCHeuristics=" + h,
+ h,
"-XX:-" + b,
"-version"
);
@@ -83,7 +83,7 @@
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UseShenandoahGC",
- "-XX:ShenandoahGCHeuristics=" + h,
+ h,
"-XX:-" + b,
"-version"
);
--- a/test/hotspot/jtreg/gc/stress/CriticalNativeStress.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/stress/CriticalNativeStress.java Mon Jul 22 11:08:27 2019 +0530
@@ -43,12 +43,13 @@
* @library /
* @requires (os.arch =="x86_64" | os.arch == "amd64") & vm.gc.Shenandoah & !vm.graal.enabled
* @summary test argument pinning by nmethod wrapper of critical native method
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+ShenandoahDegeneratedGC -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
*
* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -Xmx256M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
- * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
*/
public class CriticalNativeStress {
private static Random rand = new Random();
--- a/test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithShenandoah.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithShenandoah.java Mon Jul 22 11:08:27 2019 +0530
@@ -34,19 +34,105 @@
* @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
*
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahVerify -XX:+ShenandoahDegeneratedGC gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahVerify -XX:-ShenandoahDegeneratedGC gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahVerify -XX:+ShenandoahDegeneratedGC
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahVerify -XX:-ShenandoahDegeneratedGC
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ */
+
+/*
+ * @test TestGCBasherWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
*
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ */
+
+/*
+ * @test TestGCBasherWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
*
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ */
+
+/*
+ * @test TestGCBasherWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
*
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ */
+
+/*
+ * @test TestGCBasherWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
*/
public class TestGCBasherWithShenandoah {
public static void main(String[] args) throws IOException {
--- a/test/hotspot/jtreg/gc/stress/gclocker/TestGCLockerWithShenandoah.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/stress/gclocker/TestGCLockerWithShenandoah.java Mon Jul 22 11:08:27 2019 +0530
@@ -30,10 +30,25 @@
* @library /
* @requires vm.gc.Shenandoah & !vm.graal.enabled
* @summary Stress Shenandoah's JNI handling by calling GetPrimitiveArrayCritical while concurrently filling up old gen.
- * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+ShenandoahVerify -XX:+UseShenandoahGC gc.stress.gclocker.TestGCLockerWithShenandoah
- * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC gc.stress.gclocker.TestGCLockerWithShenandoah
- * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahOOMDuringEvacALot -XX:ShenandoahGCHeuristics=aggressive gc.stress.gclocker.TestGCLockerWithShenandoah
- * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC -XX:+ShenandoahAllocFailureALot -XX:ShenandoahGCHeuristics=aggressive gc.stress.gclocker.TestGCLockerWithShenandoah
+ *
+ * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:+ShenandoahVerify
+ * gc.stress.gclocker.TestGCLockerWithShenandoah
+ *
+ * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC
+ * gc.stress.gclocker.TestGCLockerWithShenandoah
+ *
+ * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * gc.stress.gclocker.TestGCLockerWithShenandoah
+ *
+ * @run main/native/othervm/timeout=200 -Xlog:gc*=info -Xms1500m -Xmx1500m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * gc.stress.gclocker.TestGCLockerWithShenandoah
*/
public class TestGCLockerWithShenandoah {
public static void main(String[] args) {
--- a/test/hotspot/jtreg/gc/stress/gcold/TestGCOldWithShenandoah.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/stress/gcold/TestGCOldWithShenandoah.java Mon Jul 22 11:08:27 2019 +0530
@@ -31,22 +31,93 @@
* @requires vm.gc.Shenandoah & !vm.graal.enabled
* @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
*
- * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahDegeneratedGC
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahDegeneratedGC
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ */
+
+/*
+ * @test TestGCOldWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
*
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahAllocFailureALot gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * -XX:+ShenandoahVerify
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ */
+
+/*
+ * @test TestGCOldWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
*
- * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahVerify gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahVerify gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahOOMDuringEvacALot
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * -XX:+ShenandoahAllocFailureALot
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
*
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact gc.stress.gcold.TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * gc.stress.gcold.TestGCOld 50 1 20 10 10000
*/
public class TestGCOldWithShenandoah {
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithShenandoah.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithShenandoah.java Mon Jul 22 11:08:27 2019 +0530
@@ -31,9 +31,30 @@
* @library /
* @requires vm.gc.Shenandoah & !vm.graal.enabled
* @summary Stress the Shenandoah GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+ShenandoahVerify -XX:+UseShenandoahGC gc.stress.systemgc.TestSystemGCWithShenandoah 270
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+ShenandoahVerify -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal gc.stress.systemgc.TestSystemGCWithShenandoah 270
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC gc.stress.systemgc.TestSystemGCWithShenandoah 270
+ *
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC
+ * -XX:+ShenandoahVerify
+ * gc.stress.systemgc.TestSystemGCWithShenandoah 270
+ *
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC
+ * gc.stress.systemgc.TestSystemGCWithShenandoah 270
+ */
+
+/*
+ * @test TestSystemGCWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC full GC by allocating objects of different lifetimes concurrently with System.gc().
+ *
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
+ * -XX:+ShenandoahVerify
+ * gc.stress.systemgc.TestSystemGCWithShenandoah 270
+ *
*/
public class TestSystemGCWithShenandoah {
public static void main(String[] args) throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/CheckUnhandledOops/TestOutOfMemory.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8227766
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+CheckUnhandledOops -Xmx100m TestOutOfMemory
+ */
+
+public class TestOutOfMemory {
+ public static void main(java.lang.String[] unused) {
+ final int BIG = 0x100000;
+ // Getting OOM breaks the unhandled oop detector
+ try {
+ int[][] X = new int[BIG][];
+ for (int i = 0; i < BIG; i++) {
+ X[i] = new int[BIG];
+ System.out.println("length = " + X.length);
+ }
+ } catch (OutOfMemoryError oom) {
+ System.out.println("OOM expected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invocationC1Tests.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8226956
+ * @summary Run invocation tests against C1 compiler
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * java.base/jdk.internal.misc
+ * @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
+ * shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
+ * shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
+ * @compile invokespecial/Checker.java invokespecial/ClassGenerator.java invokespecial/Generator.java
+ * invokevirtual/Checker.java invokevirtual/ClassGenerator.java invokevirtual/Generator.java
+ * invokeinterface/Checker.java invokeinterface/ClassGenerator.java invokeinterface/Generator.java
+ *
+ * @run main/othervm/timeout=1800 invocationC1Tests
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class invocationC1Tests {
+
+ public static void runTest(String whichTests, String classFileVersion) throws Exception {
+ System.out.println("\nC1 invocation tests, Tests: " + whichTests +
+ ", class file version: " + classFileVersion);
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M",
+ "-Xcomp", "-XX:TieredStopAtLevel=1", whichTests,
+ "--classfile_version=" + classFileVersion);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("EXECUTION STATUS: PASSED");
+ output.shouldHaveExitValue(0);
+ } catch (Throwable e) {
+ System.out.println(
+ "\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
+ " the test case failed because method B.m was invoked but the test " +
+ "expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
+ " means that an AbstractMethodError exception was thrown but the test" +
+ " case expected method C.m to be invoked.");
+ System.out.println(
+ "\nAlso note that passing --dump to invoke*.Generator will" +
+ " dump the generated classes (for debugging purposes).\n");
+ System.exit(1);
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ // Get current major class file version and test with it.
+ byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
+ int major_version = klassbuf[6] << 8 | klassbuf[7];
+ runTest("invokespecial.Generator", String.valueOf(major_version));
+ runTest("invokeinterface.Generator", String.valueOf(major_version));
+
+ // Uncomment this test once JDK-8226588 is fixed
+ // runTest("invokevirtual.Generator", String.valueOf(major_version));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8226956
+ * @requires vm.jvmci
+ * @summary Run invocation tests against Graal compiler
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * java.base/jdk.internal.misc
+ * @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
+ * shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
+ * shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
+ * @compile invokespecial/Checker.java invokespecial/ClassGenerator.java invokespecial/Generator.java
+ * invokevirtual/Checker.java invokevirtual/ClassGenerator.java invokevirtual/Generator.java
+ * invokeinterface/Checker.java invokeinterface/ClassGenerator.java invokeinterface/Generator.java
+ *
+ * @run main/othervm/timeout=1800 invocationGraalTests
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class invocationGraalTests {
+
+ public static void runTest(String whichTests, String classFileVersion) throws Exception {
+ System.out.println("\nGraal invocation tests, Tests: " + whichTests +
+ ", class file version: " + classFileVersion);
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M",
+ "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:+UseJVMCICompiler",
+ whichTests, "--classfile_version=" + classFileVersion);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("EXECUTION STATUS: PASSED");
+ output.shouldHaveExitValue(0);
+ } catch (Throwable e) {
+ System.out.println(
+ "\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
+ " the test case failed because method B.m was invoked but the test " +
+ "expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
+ " means that an AbstractMethodError exception was thrown but the test" +
+ " case expected method C.m to be invoked.");
+ System.out.println(
+ "\nAlso note that passing --dump to invoke*.Generator will" +
+ " dump the generated classes (for debugging purposes).\n");
+ System.exit(1);
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ // Get current major class file version and test with it.
+ byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
+ int major_version = klassbuf[6] << 8 | klassbuf[7];
+ runTest("invokevirtual.Generator", String.valueOf(major_version));
+ runTest("invokespecial.Generator", String.valueOf(major_version));
+ runTest("invokeinterface.Generator", String.valueOf(major_version));
+ }
+}
--- a/test/hotspot/jtreg/runtime/InvocationTests/invokeinterface/Checker.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokeinterface/Checker.java Mon Jul 22 11:08:27 2019 +0530
@@ -67,15 +67,13 @@
int modifiers = method.getModifiers();
// Check whether obtained method is public and isn't abstract
- if ( Modifier.isPublic(modifiers))
- {
+ if ( Modifier.isPublic(modifiers)) {
if (Modifier.isAbstract(modifiers)) {
return "java.lang.AbstractMethodError";
} else {
- return String.format("%s.%s"
- , method.getDeclaringClass().getSimpleName()
- , methodName
- );
+ return String.format("%s.%s",
+ method.getDeclaringClass().getSimpleName(),
+ methodName);
}
} else {
// IAE is thrown when located method isn't PUBLIC
--- a/test/hotspot/jtreg/runtime/InvocationTests/invokespecial/Checker.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokespecial/Checker.java Mon Jul 22 11:08:27 2019 +0530
@@ -34,16 +34,12 @@
}
public String check (Class callerClass) {
- /*
- * If objectref is null, the invokespecial instruction throws a NullPointerException.
- */
+ // If objectref is null, the invokespecial instruction throws a NullPointerException.
if (dynamicTargetClass == null) {
return "java.lang.NullPointerException";
}
- /*
- * TODO: find a citiation from spec for this case
- */
+ // TODO: find a citation from spec for this case
Method resolvedMethod;
try {
// May throw VerifyError
@@ -56,15 +52,13 @@
return "java.lang.NoSuchMethodError";
}
- /*
- * If:
- * - the resolved method is protected (4.7)
- * - it is a member of a superclass of the current class
- * - the method is not declared in the same run-time package (5.3) as the current class
- * then:
- * the class of objectref must be either the current class or a subclass of the
- * current class.
- */
+ // If:
+ // - the resolved method is protected (4.7)
+ // - it is a member of a superclass of the current class
+ // - the method is not declared in the same run-time package (5.3) as the current class
+ // then:
+ // the class of objectref must be either the current class or a subclass of the
+ // current class.
if (Modifier.isProtected(resolvedMethod.getModifiers())) {
Method methodInSuperclass = getMethodInHierarchy(resolvedMethod.getDeclaringClass().getSuperclass());
--- a/test/hotspot/jtreg/runtime/InvocationTests/invokevirtual/Checker.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokevirtual/Checker.java Mon Jul 22 11:08:27 2019 +0530
@@ -88,7 +88,7 @@
return null;
}
- // Dynamic target doesn't have desired method, so check it's superclass
+ // Dynamic target doesn't have desired method, so check its superclass
if (dynamicTargetMethod == null) {
return getOverriddenMethod(staticTarget, dynamicTarget.getSuperclass());
} else {
@@ -109,11 +109,9 @@
String staticTargetPkg = getClassPackageName(staticTarget);
String dynamicTargetPkg = getClassPackageName(dynamicTarget);
- if ( isPublic || isProtected
- || ( !isPublic && !isProtected && !isPrivate
- && staticTargetPkg.equals(dynamicTargetPkg)
- ))
- {
+ if (isPublic || isProtected
+ || (!isPublic && !isProtected && !isPrivate
+ && staticTargetPkg.equals(dynamicTargetPkg))) {
return dynamicTargetMethod;
}
}
--- a/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java Mon Jul 22 11:08:27 2019 +0530
@@ -31,9 +31,6 @@
import java.util.List;
import java.util.ArrayList;
-/**
- *
- */
public abstract class AbstractGenerator {
protected final boolean dumpClasses;
protected final boolean executeTests;
--- a/test/hotspot/jtreg/runtime/InvocationTests/shared/AccessCheck.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/AccessCheck.java Mon Jul 22 11:08:27 2019 +0530
@@ -26,8 +26,7 @@
import static jdk.internal.org.objectweb.asm.Opcodes.*;
-/**
- *
+/*
* @author vi158347
*/
public class AccessCheck {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/TLS/T.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, Google Inc. All rights reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.lang.ProcessBuilder;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class T {
+ public static boolean run() {
+ boolean res = false;
+ String echoInput = "foo";
+ ProcessBuilder pb = new ProcessBuilder("echo", echoInput);
+
+ try {
+ // Starting a ProcessBuilder causes the process reaper thread to be
+ // created. The process reaper thread has small stack size. In JDK
+ // 13, the REAPER_DEFAULT_STACKSIZE is 128K. With JDK 8, it is 32K.
+ // Using the process reaper thread can demonstrate the TLS problem.
+ // The reaper thread can fail with StackOverflow in one of the
+ // failure mode with certain TLS sizes. In another observed
+ // failure mode the VM fails to create a thread with error message
+ // 'Failed to start thread - pthread_create failed'.
+ System.out.println("Starting a new process ...");
+ Process process = pb.start();
+ process.waitFor();
+ String echoOutput = output(process.getInputStream());
+ System.out.println("Echo Output: " + echoOutput);
+ if (echoOutput.equals(echoInput)) {
+ res = true;
+ } else {
+ // 'res' is false, fail
+ System.out.println("Unexpected Echo output: " + echoOutput +
+ ", expects: " + echoInput);
+ }
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ e.printStackTrace();
+ }
+ return res;
+ }
+
+ private static String output(InputStream inputStream) throws IOException {
+ String s = "";
+ try (BufferedReader br =
+ new BufferedReader(new InputStreamReader(inputStream))) {
+ s = br.readLine();
+ }
+ return s;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/TLS/exestack-tls.c Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2019, Google Inc. All rights reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Declare the thread local variable(s) in the main executable. This can be
+// used to demonstrate the issues associated with the on-stack static TLS blocks
+// that may cause insufficient stack space. The dynamic TLS blocks for shared
+// objects (such as a JNI library) loaded via dlopen are not allocated on stack.
+__thread int tls[128 * 1024];
+
+JNIEnv* create_vm(JavaVM **jvm, char* argTLS) {
+ JNIEnv* env;
+ JavaVMInitArgs args;
+ JavaVMOption options[3];
+ args.version = JNI_VERSION_1_8;
+ args.nOptions = 3;
+ char classpath[4096];
+ snprintf(classpath, sizeof classpath,
+ "-Djava.class.path=%s", getenv("CLASSPATH"));
+ options[0].optionString = classpath;
+ options[1].optionString = "-Xlog:os+thread=info";
+ options[2].optionString = argTLS;
+ args.options = &options[0];
+ args.ignoreUnrecognized = 0;
+ int rv;
+ rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
+ if (rv < 0) return NULL;
+ return env;
+}
+
+int run(jboolean addTLS) {
+ JavaVM *jvm;
+ jclass testClass;
+ jmethodID runMethod;
+ char* argTLS;
+ int res = -1;
+
+ if (addTLS) {
+ argTLS = "-XX:+AdjustStackSizeForTLS";
+ } else {
+ argTLS = "-XX:-AdjustStackSizeForTLS"; // default
+ }
+ printf("Running test with %s ...\n", argTLS);
+ JNIEnv *env = create_vm(&jvm, argTLS);
+
+ // Run T.run() and check result:
+ // - Expect T.run() to return 'true' when stack size is adjusted for TLS,
+ // return 0 if so
+ // - Expect T.run() to return 'false' if stack size is not adjusted for
+ // TLS, return 0 if so
+ // Return -1 (fail) for other cases
+ testClass = (*env)->FindClass(env, "T");
+ runMethod = (*env)->GetStaticMethodID(env, testClass, "run", "()Z");
+ if ((*env)->CallStaticBooleanMethod(env, testClass, runMethod, NULL)) {
+ if (addTLS) {
+ // expect T.run() to return 'true'
+ res = 0;
+ }
+ } else {
+ if (!addTLS) {
+ // expect T.run() to return 'false'
+ res = 0;
+ }
+ }
+
+ if (res == 0) {
+ printf("Test passed with %s\n", argTLS);
+ } else {
+ printf("Test failed with %s\n", argTLS);
+ }
+ return res;
+}
+
+int main(int argc, char **argv) {
+ if (argc == 2 && strcmp(argv[1], "-add_tls") == 0) {
+ return run(JNI_TRUE);
+ } else {
+ return run(JNI_FALSE);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/TLS/testtls.sh Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,52 @@
+# Copyright (c) 2019, Google Inc. All rights reserved.
+# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#!/bin/sh
+
+#
+# @test testtls.sh
+# @summary Test with extra TLS size.
+# @requires os.family == "linux"
+# @compile T.java
+# @run shell testtls.sh
+#
+
+if [ "${TESTSRC}" = "" ]
+then
+ TESTSRC=${PWD}
+ echo "TESTSRC not set. Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
+LD_LIBRARY_PATH=.:${TESTJAVA}/lib/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+# Test 1) Run with stack size adjusted for TLS
+${TESTNATIVEPATH}/stack-tls -add_tls || exit $?
+
+# Test 2) Run with no stack size adjustment and expect failure.
+#
+# Potential failures include StackOverflowError, thread creation failures,
+# crashes, and etc. The test case can be used to demonstrate the TLS issue
+# but is excluded from running in regular testing.
+#${TESTNATIVEPATH}/stack-tls || exit $?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/VtableTests/VTableTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8226798
+ * @summary Check that the vTable for class C gets set up without causing
+ * an assertion failure.
+ * @compile pkg/A.java
+ * @run main VTableTest
+ */
+
+public class VTableTest {
+
+ interface Intf {
+ public default void m() { }
+ public default void unusedButNeededToReproduceIssue() { }
+ }
+
+ static class B extends pkg.A implements Intf {
+ }
+
+ static class C extends B {
+ public void m() { System.out.println("In C.m()"); }
+ }
+
+ public static void main(String[] args) {
+ new C().m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/VtableTests/pkg/A.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+public class A {
+ void m() { }
+}
--- a/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java Mon Jul 22 11:08:27 2019 +0530
@@ -61,13 +61,17 @@
public class SharedArchiveConsistency {
public static WhiteBox wb;
- public static int offset_magic; // FileMapHeader::_magic
- public static int sp_offset_crc; // CDSFileMapRegion::_crc
+ public static int offset_magic; // CDSFileMapHeaderBase::_magic
+ public static int offset_version; // CDSFileMapHeaderBase::_version
+ public static int offset_jvm_ident; // FileMapHeader::_jvm_ident
+ public static int sp_offset_crc; // CDSFileMapRegion::_crc
+ public static int offset_paths_misc_info_size;
public static int file_header_size = -1;// total size of header, variant, need calculation
public static int CDSFileMapRegion_size; // size of CDSFileMapRegion
public static int sp_offset; // offset of CDSFileMapRegion
public static int sp_used_offset; // offset of CDSFileMapRegion::_used
public static int size_t_size; // size of size_t
+ public static int int_size; // size of int
public static File jsa; // will be updated during test
public static File orgJsaFile; // kept the original file not touched.
@@ -94,6 +98,8 @@
public static void getFileOffsetInfo() throws Exception {
wb = WhiteBox.getWhiteBox();
offset_magic = wb.getOffsetForName("FileMapHeader::_magic");
+ offset_version = wb.getOffsetForName("FileMapHeader::_version");
+ offset_jvm_ident = wb.getOffsetForName("FileMapHeader::_jvm_ident");
sp_offset_crc = wb.getOffsetForName("CDSFileMapRegion::_crc");
try {
int nonExistOffset = wb.getOffsetForName("FileMapHeader::_non_exist_offset");
@@ -113,13 +119,13 @@
return file_header_size;
}
// this is not real header size, it is struct size
- int int_size = wb.getOffsetForName("int_size");
+ int_size = wb.getOffsetForName("int_size");
file_header_size = wb.getOffsetForName("file_header_size");
- int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
+ offset_paths_misc_info_size = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
offset_magic;
- int path_misc_info_size = (int)readInt(fc, offset_path_misc_info, int_size);
- file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size);
- System.out.println("offset_path_misc_info = " + offset_path_misc_info);
+ int path_misc_info_size = (int)readInt(fc, offset_paths_misc_info_size, int_size);
+ file_header_size += path_misc_info_size;
+ System.out.println("offset_paths_misc_info_size = " + offset_paths_misc_info_size);
System.out.println("path_misc_info_size = " + path_misc_info_size);
System.out.println("file_header_size = " + file_header_size);
file_header_size = (int)align_up_page(file_header_size);
@@ -160,15 +166,15 @@
fc.force(true);
}
- public static FileChannel getFileChannel() throws Exception {
+ public static FileChannel getFileChannel(File jsaFile) throws Exception {
List<StandardOpenOption> arry = new ArrayList<StandardOpenOption>();
arry.add(READ);
arry.add(WRITE);
- return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry));
+ return FileChannel.open(jsaFile.toPath(), new HashSet<StandardOpenOption>(arry));
}
- public static void modifyJsaContentRandomly() throws Exception {
- FileChannel fc = getFileChannel();
+ public static void modifyJsaContentRandomly(File jsaFile) throws Exception {
+ FileChannel fc = getFileChannel(jsaFile);
// corrupt random area in the data areas
long[] used = new long[num_regions]; // record used bytes
long start0, start, end, off;
@@ -210,8 +216,8 @@
return used;
}
- public static boolean modifyJsaContent(int region) throws Exception {
- FileChannel fc = getFileChannel();
+ public static boolean modifyJsaContent(int region, File jsaFile) throws Exception {
+ FileChannel fc = getFileChannel(jsaFile);
byte[] buf = new byte[4096];
ByteBuffer bbuf = ByteBuffer.wrap(buf);
@@ -248,8 +254,8 @@
return true;
}
- public static void modifyJsaHeader() throws Exception {
- FileChannel fc = getFileChannel();
+ public static void modifyJsaHeader(File jsaFile) throws Exception {
+ FileChannel fc = getFileChannel(jsaFile);
// screw up header info
byte[] buf = new byte[getFileHeaderSize(fc)];
ByteBuffer bbuf = ByteBuffer.wrap(buf);
@@ -259,6 +265,30 @@
}
}
+ public static void modifyJvmIdent() throws Exception {
+ FileChannel fc = getFileChannel(jsa);
+ int headerSize = getFileHeaderSize(fc);
+ System.out.println(" offset_jvm_ident " + offset_jvm_ident);
+ byte[] buf = new byte[256];
+ ByteBuffer bbuf = ByteBuffer.wrap(buf);
+ writeData(fc, (long)offset_jvm_ident, bbuf);
+ if (fc.isOpen()) {
+ fc.close();
+ }
+ }
+
+ public static void modifyHeaderIntField(long offset, int value) throws Exception {
+ FileChannel fc = getFileChannel(jsa);
+ int headerSize = getFileHeaderSize(fc);
+ System.out.println(" offset " + offset);
+ byte[] buf = ByteBuffer.allocate(4).putInt(value).array();
+ ByteBuffer bbuf = ByteBuffer.wrap(buf);
+ writeData(fc, offset, bbuf);
+ if (fc.isOpen()) {
+ fc.close();
+ }
+ }
+
public static void copyFile(File from, File to) throws Exception {
if (to.exists()) {
if(!to.delete()) {
@@ -348,10 +378,10 @@
// test, should pass
System.out.println("1. Normal, should pass but may fail\n");
- String[] execArgs = {"-cp", jarFile, "Hello"};
+ String[] execArgs = {"-Xlog:cds", "-cp", jarFile, "Hello"};
// tests that corrupt contents of the archive need to run with
// VerifySharedSpaces enabled to detect inconsistencies
- String[] verifyExecArgs = {"-XX:+VerifySharedSpaces", "-cp", jarFile, "Hello"};
+ String[] verifyExecArgs = {"-Xlog:cds", "-XX:+VerifySharedSpaces", "-cp", jarFile, "Hello"};
OutputAnalyzer output = TestCommon.execCommon(execArgs);
@@ -373,10 +403,36 @@
orgJsaFile = new File(new File(currentDir), "appcds.jsa.bak");
copyFile(jsa, orgJsaFile);
-
// modify jsa header, test should fail
System.out.println("\n2. Corrupt header, should fail\n");
- modifyJsaHeader();
+ modifyJsaHeader(jsa);
+ output = TestCommon.execCommon(execArgs);
+ output.shouldContain("The shared archive file has a bad magic number");
+ output.shouldNotContain("Checksum verification failed");
+
+ copyFile(orgJsaFile, jsa);
+ // modify _jvm_ident and _paths_misc_info_size, test should fail
+ System.out.println("\n2a. Corrupt _jvm_ident and _paths_misc_info_size, should fail\n");
+ modifyJvmIdent();
+ modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE);
+ output = TestCommon.execCommon(execArgs);
+ output.shouldContain("The shared archive file was created by a different version or build of HotSpot");
+ output.shouldNotContain("Checksum verification failed");
+
+ copyFile(orgJsaFile, jsa);
+ // modify _magic and _paths_misc_info_size, test should fail
+ System.out.println("\n2b. Corrupt _magic and _paths_misc_info_size, should fail\n");
+ modifyHeaderIntField(offset_magic, 0x00000000);
+ modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE);
+ output = TestCommon.execCommon(execArgs);
+ output.shouldContain("The shared archive file has a bad magic number");
+ output.shouldNotContain("Checksum verification failed");
+
+ copyFile(orgJsaFile, jsa);
+ // modify _version and _paths_misc_info_size, test should fail
+ System.out.println("\n2c. Corrupt _version and _paths_misc_info_size, should fail\n");
+ modifyHeaderIntField(offset_version, 0x00000000);
+ modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE);
output = TestCommon.execCommon(execArgs);
output.shouldContain("The shared archive file has the wrong version");
output.shouldNotContain("Checksum verification failed");
@@ -387,8 +443,9 @@
for (int i=0; i<num_regions; i++) {
newJsaFile = new File(TestCommon.getNewArchiveName(shared_region_name[i]));
copyFile(orgJsaFile, newJsaFile);
- if (modifyJsaContent(i)) {
- testAndCheck(execArgs);
+ TestCommon.setCurrentArchiveName(newJsaFile.toString());
+ if (modifyJsaContent(i, newJsaFile)) {
+ testAndCheck(verifyExecArgs);
}
}
@@ -396,15 +453,17 @@
System.out.println("\n4. Corrupt Header and Content, should fail\n");
newJsaFile = new File(TestCommon.getNewArchiveName("header-and-content"));
copyFile(orgJsaFile, newJsaFile);
- modifyJsaHeader();
- modifyJsaContent(0); // this will not be reached since failed on header change first
+ TestCommon.setCurrentArchiveName(newJsaFile.toString());
+ modifyJsaHeader(newJsaFile);
+ modifyJsaContent(0, newJsaFile); // this will not be reached since failed on header change first
output = TestCommon.execCommon(execArgs);
- output.shouldContain("The shared archive file has the wrong version");
+ output.shouldContain("The shared archive file has a bad magic number");
output.shouldNotContain("Checksum verification failed");
// delete bytes in data section
System.out.println("\n5. Delete bytes at beginning of data section, should fail\n");
copyFile(orgJsaFile, jsa, true);
+ TestCommon.setCurrentArchiveName(jsa.toString());
testAndCheck(verifyExecArgs);
// insert bytes in data section forward
@@ -415,7 +474,8 @@
System.out.println("\n7. modify Content in random areas, should fail\n");
newJsaFile = new File(TestCommon.getNewArchiveName("random-areas"));
copyFile(orgJsaFile, newJsaFile);
- modifyJsaContentRandomly();
+ TestCommon.setCurrentArchiveName(newJsaFile.toString());
+ modifyJsaContentRandomly(newJsaFile);
testAndCheck(verifyExecArgs);
}
}
--- a/test/hotspot/jtreg/runtime/appcds/TestCommon.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/TestCommon.java Mon Jul 22 11:08:27 2019 +0530
@@ -90,6 +90,10 @@
return currentArchiveName;
}
+ public static void setCurrentArchiveName(String archiveName) {
+ currentArchiveName = archiveName;
+ }
+
public static String getNewArchiveName() {
return getNewArchiveName(null);
}
--- a/test/hotspot/jtreg/runtime/clinit/ClassInitBarrier.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/clinit/ClassInitBarrier.java Mon Jul 22 11:08:27 2019 +0530
@@ -27,24 +27,24 @@
*
* @requires !vm.graal.enabled
*
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -Xint -DTHROW=false ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -Xint -DTHROW=true ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -Xint -DTHROW=false -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -Xint -DTHROW=true -Xcheck:jni ClassInitBarrier
*
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=false ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=true ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=false -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=true -Xcheck:jni ClassInitBarrier
*
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=false ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=true ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=false -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=true -Xcheck:jni ClassInitBarrier
*
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=false -XX:CompileCommand=dontinline,*::static* ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=true -XX:CompileCommand=dontinline,*::static* ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=false -XX:CompileCommand=dontinline,*::static* ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=true -XX:CompileCommand=dontinline,*::static* ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=false -XX:CompileCommand=dontinline,*::static* -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=true -XX:CompileCommand=dontinline,*::static* -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=false -XX:CompileCommand=dontinline,*::static* -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=true -XX:CompileCommand=dontinline,*::static* -Xcheck:jni ClassInitBarrier
*
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=false -XX:CompileCommand=exclude,*::static* ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=true -XX:CompileCommand=exclude,*::static* ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=false -XX:CompileCommand=exclude,*::static* ClassInitBarrier
- * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=true -XX:CompileCommand=exclude,*::static* ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=false -XX:CompileCommand=exclude,*::static* -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:TieredStopAtLevel=1 -DTHROW=true -XX:CompileCommand=exclude,*::static* -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=false -XX:CompileCommand=exclude,*::static* -Xcheck:jni ClassInitBarrier
+ * @run main/othervm/native -Xbatch -XX:CompileCommand=dontinline,*::test* -XX:-TieredCompilation -DTHROW=true -XX:CompileCommand=exclude,*::static* -Xcheck:jni ClassInitBarrier
*/
import jdk.test.lib.Asserts;
@@ -70,6 +70,10 @@
static class Test {
static class A {
static {
+ if (!init(B.class)) {
+ throw new Error("init failed");
+ }
+
changePhase(Phase.IN_PROGRESS);
runTests(); // interpreted mode
warmup(); // trigger compilation
@@ -89,13 +93,15 @@
int f;
void m() {}
+
+ static native boolean init(Class<B> cls);
}
static class B extends A {}
- static void testInvokeStatic(Runnable action) { A.staticM(action); }
- static void testInvokeStaticSync(Runnable action) { A.staticS(action); }
- static void testInvokeStaticNative(Runnable action) { A.staticN(action); }
+ static void testInvokeStatic(Runnable action) { A.staticM(action); }
+ static void testInvokeStaticSync(Runnable action) { A.staticS(action); }
+ static void testInvokeStaticNative(Runnable action) { A.staticN(action); }
static int testGetStatic(Runnable action) { int v = A.staticF; action.run(); return v; }
static void testPutStatic(Runnable action) { A.staticF = 1; action.run(); }
@@ -106,20 +112,45 @@
static void testPutField(A recv, Runnable action) { recv.f = 1; action.run(); }
static void testInvokeVirtual(A recv, Runnable action) { recv.m(); action.run(); }
+ static native void testInvokeStaticJNI(Runnable action);
+ static native void testInvokeStaticSyncJNI(Runnable action);
+ static native void testInvokeStaticNativeJNI(Runnable action);
+
+ static native int testGetStaticJNI(Runnable action);
+ static native void testPutStaticJNI(Runnable action);
+ static native A testNewInstanceAJNI(Runnable action);
+ static native B testNewInstanceBJNI(Runnable action);
+
+ static native int testGetFieldJNI(A recv, Runnable action);
+ static native void testPutFieldJNI(A recv, Runnable action);
+ static native void testInvokeVirtualJNI(A recv, Runnable action);
+
static void runTests() {
checkBlockingAction(Test::testInvokeStatic); // invokestatic
+ checkBlockingAction(Test::testInvokeStaticSync); // invokestatic
checkBlockingAction(Test::testInvokeStaticNative); // invokestatic
- checkBlockingAction(Test::testInvokeStaticSync); // invokestatic
checkBlockingAction(Test::testGetStatic); // getstatic
checkBlockingAction(Test::testPutStatic); // putstatic
checkBlockingAction(Test::testNewInstanceA); // new
+ checkNonBlockingAction(Test::testInvokeStaticJNI); // invokestatic
+ checkNonBlockingAction(Test::testInvokeStaticSyncJNI); // invokestatic
+ checkNonBlockingAction(Test::testInvokeStaticNativeJNI); // invokestatic
+ checkNonBlockingAction(Test::testGetStaticJNI); // getstatic
+ checkNonBlockingAction(Test::testPutStaticJNI); // putstatic
+ checkBlockingAction(Test::testNewInstanceAJNI); // new
+
A recv = testNewInstanceB(NON_BLOCKING.get()); // trigger B initialization
checkNonBlockingAction(Test::testNewInstanceB); // new: NO BLOCKING: same thread: A being initialized, B fully initialized
checkNonBlockingAction(recv, Test::testGetField); // getfield
checkNonBlockingAction(recv, Test::testPutField); // putfield
checkNonBlockingAction(recv, Test::testInvokeVirtual); // invokevirtual
+
+ checkNonBlockingAction(Test::testNewInstanceBJNI); // new: NO BLOCKING: same thread: A being initialized, B fully initialized
+ checkNonBlockingAction(recv, Test::testGetFieldJNI); // getfield
+ checkNonBlockingAction(recv, Test::testPutFieldJNI); // putfield
+ checkNonBlockingAction(recv, Test::testInvokeVirtualJNI); // invokevirtual
}
static void warmup() {
--- a/test/hotspot/jtreg/runtime/clinit/libClassInitBarrier.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/runtime/clinit/libClassInitBarrier.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -25,6 +25,17 @@
static jmethodID methodId;
+static jclass test_class_A;
+static jclass test_class_B;
+
+static jmethodID test_staticM_id;
+static jmethodID test_staticS_id;
+static jmethodID test_staticN_id;
+static jmethodID test_A_m_id;
+
+static jfieldID test_staticF_id;
+static jfieldID test_A_f_id;
+
extern "C" {
JNIEXPORT jboolean JNICALL Java_ClassInitBarrier_init(JNIEnv* env, jclass cls) {
jclass runnable = env->FindClass("java/lang/Runnable");
@@ -36,7 +47,103 @@
return JNI_TRUE;
}
+ JNIEXPORT jboolean JNICALL Java_ClassInitBarrier_00024Test_00024A_init(JNIEnv* env, jclass cls, jclass arg1) {
+ test_class_A = (jclass)env->NewGlobalRef(cls);
+ if (test_class_A == NULL) return JNI_FALSE;
+
+ test_class_B = (jclass)env->NewGlobalRef(arg1);
+ if (test_class_B == NULL) return JNI_FALSE;
+
+ test_staticM_id = env->GetStaticMethodID(test_class_A, "staticM", "(Ljava/lang/Runnable;)V");
+ if (test_staticM_id == NULL) return JNI_FALSE;
+
+ test_staticS_id = env->GetStaticMethodID(test_class_A, "staticS", "(Ljava/lang/Runnable;)V");
+ if (test_staticS_id == NULL) return JNI_FALSE;
+
+ test_staticN_id = env->GetStaticMethodID(test_class_A, "staticN", "(Ljava/lang/Runnable;)V");
+ if (test_staticN_id == NULL) return JNI_FALSE;
+
+ test_A_m_id = env->GetMethodID(test_class_A, "m", "()V");
+ if (test_A_m_id == NULL) return JNI_FALSE;
+
+ test_staticF_id = env->GetStaticFieldID(test_class_A, "staticF", "I");
+ if (test_staticF_id == NULL) return JNI_FALSE;
+
+ test_A_f_id = env->GetFieldID(test_class_A, "f", "I");
+ if (test_A_f_id == NULL) return JNI_FALSE;
+
+ return JNI_TRUE;
+ }
+
JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_00024A_staticN(JNIEnv* env, jclass cls, jobject action) {
env->CallVoidMethod(action, methodId);
}
+
+ JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_testInvokeStaticJNI(JNIEnv* env, jclass cls, jobject action) {
+ env->CallStaticVoidMethod(test_class_A, test_staticM_id, action);
+ }
+
+ JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_testInvokeStaticSyncJNI(JNIEnv* env, jclass cls, jobject action) {
+ env->CallStaticVoidMethod(test_class_A, test_staticS_id, action);
+ }
+
+ JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_testInvokeStaticNativeJNI(JNIEnv* env, jclass cls, jobject action) {
+ env->CallStaticVoidMethod(test_class_A, test_staticN_id, action);
+ }
+
+ JNIEXPORT jint JNICALL Java_ClassInitBarrier_00024Test_testGetStaticJNI(JNIEnv* env, jclass cls, jobject action) {
+ jint v = env->GetStaticIntField(test_class_A, test_staticF_id); // int v = A.staticF;
+ env->CallVoidMethod(action, methodId); // action.run();
+ return v;
+ }
+
+ JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_testPutStaticJNI(JNIEnv* env, jclass cls, jobject action) {
+ env->SetStaticIntField(test_class_A, test_staticF_id, 1); // A.staticF = 1;
+ env->CallVoidMethod(action, methodId); // action.run();
+ }
+
+ JNIEXPORT jobject JNICALL Java_ClassInitBarrier_00024Test_testNewInstanceAJNI(JNIEnv* env, jclass cls, jobject action) {
+ jobject obj = env->AllocObject(test_class_A); // A obj = new A();
+ if (env->ExceptionOccurred()) {
+ return NULL;
+ } else if (obj == NULL) {
+ jclass errorClass = env->FindClass("java/lang/AssertionError");
+ int ret = env->ThrowNew(errorClass, "JNI: AllocObject: allocation failed, but no exception thrown");
+ return NULL;
+ }
+ env->CallVoidMethod(action, methodId); // action.run();
+ return obj;
+ }
+
+ JNIEXPORT jobject JNICALL Java_ClassInitBarrier_00024Test_testNewInstanceBJNI(JNIEnv* env, jclass cls, jobject action) {
+ jobject obj = env->AllocObject(test_class_B); // B obj = new B();
+ if (env->ExceptionOccurred()) {
+ return NULL;
+ } else if (obj == NULL) {
+ jclass errorClass = env->FindClass("java/lang/AssertionError");
+ int ret = env->ThrowNew(errorClass, "JNI: AllocObject: allocation failed, but no exception thrown");
+ return NULL;
+ }
+ env->CallVoidMethod(action, methodId); // action.run();
+ return obj;
+ }
+
+ JNIEXPORT jint JNICALL Java_ClassInitBarrier_00024Test_testGetFieldJNI(JNIEnv* env, jclass cls, jobject recv, jobject action) {
+ jint v = env->GetIntField(recv, test_A_f_id); // int v = recv.f;
+ env->CallVoidMethod(action, methodId); // action.run();
+ return v;
+ }
+
+ JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_testPutFieldJNI(JNIEnv* env, jclass cls, jobject recv, jobject action) {
+ env->SetIntField(recv, test_A_f_id, 1); // A.staticF = 1;
+ env->CallVoidMethod(action, methodId); // action.run();
+ }
+
+ JNIEXPORT void JNICALL Java_ClassInitBarrier_00024Test_testInvokeVirtualJNI(JNIEnv* env, jclass cls, jobject recv, jobject action) {
+ env->CallVoidMethod(recv, test_A_m_id); // recv.m();
+ if (env->ExceptionOccurred()) {
+ return;
+ }
+ env->CallVoidMethod(action, methodId); // action.run();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/attach/ConcAttachTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8225690
+ * @requires os.family != "windows"
+ * @library /test/lib
+ * @modules jdk.attach/com.sun.tools.attach
+ * @run main ConcAttachTest
+ */
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AttachNotSupportedException;
+
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ConcAttachTest implements Runnable {
+
+ private static final int NUM_CONC_REQUESTS = 100;
+
+ private static final int THREAD_POOL_TIMEOUT_IN_SEC = 30;
+
+ private static CountDownLatch latch;
+
+ private static String strPID;
+
+ // Attach to LingeredApp concurrently.
+ public void run() {
+ VirtualMachine vm = null;
+
+ try {
+ latch.countDown();
+ latch.await();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ try {
+ vm = VirtualMachine.attach(strPID);
+ } catch (AttachNotSupportedException | IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ try {
+ vm.detach();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private static void checkAttachListenerThread() throws InterruptedException, IOException {
+ JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd");
+ jcmd.addToolArg(strPID);
+ jcmd.addToolArg("Thread.print");
+
+ ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand());
+ Process jcmdProc = pb.start();
+
+ OutputAnalyzer out = new OutputAnalyzer(jcmdProc);
+
+ jcmdProc.waitFor();
+
+ System.out.println(out.getStdout());
+ System.err.println(out.getStderr());
+
+ long numOfAttachListener = out.asLines()
+ .stream()
+ .filter(l -> l.contains("Attach Listener"))
+ .count();
+
+ Asserts.assertEquals(1L, numOfAttachListener, "AttachListener should exist only 1 thread.");
+ }
+
+ public static void main(String... args) throws Exception {
+ LingeredApp app = null;
+ latch = new CountDownLatch(NUM_CONC_REQUESTS);
+ ExecutorService pool = Executors.newFixedThreadPool(NUM_CONC_REQUESTS);
+
+ try {
+ app = LingeredApp.startApp();
+ strPID = Long.toString(app.getPid());
+
+ for (int i = 0; i < NUM_CONC_REQUESTS; i++) {
+ pool.submit(new ConcAttachTest());
+ }
+
+ pool.shutdown();
+ pool.awaitTermination(THREAD_POOL_TIMEOUT_IN_SEC, TimeUnit.SECONDS);
+
+ checkAttachListenerThread();
+ } finally {
+ LingeredApp.stopApp(app);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8225193
+ * @requires os.family != "windows"
+ * @library /test/lib
+ * @run main RemovingUnixDomainSocketTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RemovingUnixDomainSocketTest {
+
+ private static void runJCmd(long pid) throws InterruptedException, IOException {
+ JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd");
+ jcmd.addToolArg(Long.toString(pid));
+ jcmd.addToolArg("VM.version");
+
+ ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand());
+ Process jcmdProc = pb.start();
+
+ OutputAnalyzer out = new OutputAnalyzer(jcmdProc);
+
+ jcmdProc.waitFor();
+
+ System.out.println(out.getStdout());
+ System.err.println(out.getStderr());
+
+ out.stderrShouldBeEmpty();
+ }
+
+ public static void main(String... args) throws Exception {
+ LingeredApp app = null;
+ try {
+ app = LingeredApp.startApp();
+
+ // Access to Attach Listener
+ runJCmd(app.getPid());
+
+ // Remove unix domain socket file
+ var sockFile = Path.of(System.getProperty("java.io.tmpdir"),
+ ".java_pid" + app.getPid())
+ .toFile();
+ System.out.println("Remove " + sockFile.toString());
+ sockFile.delete();
+
+ // Access to Attach Listener again
+ runJCmd(app.getPid());
+ } finally {
+ LingeredApp.stopApp(app);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8209790
+ * @summary Checks ability for connecting to debug server (jstack, jmap, jinfo, jsnap)
+ * @requires vm.hasSAandCanAttach
+ * @requires os.family != "windows"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ *
+ * @run main/othervm DebugdConnectTest
+ */
+
+import java.io.IOException;
+
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+public class DebugdConnectTest {
+
+ private static OutputAnalyzer runJHSDB(String command, String id) throws IOException, InterruptedException {
+ JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+ jhsdbLauncher.addToolArg(command);
+ jhsdbLauncher.addToolArg("--connect");
+ if (id != null) {
+ jhsdbLauncher.addToolArg(id + "@localhost");
+ } else {
+ jhsdbLauncher.addToolArg("localhost");
+ }
+
+ Process jhsdb = (new ProcessBuilder(jhsdbLauncher.getCommand())).start();
+ OutputAnalyzer out = new OutputAnalyzer(jhsdb);
+
+ jhsdb.waitFor();
+
+ System.out.println(out.getStdout());
+ System.err.println(out.getStderr());
+
+ return out;
+ }
+
+ private static void runJSTACK(String id) throws IOException, InterruptedException {
+ OutputAnalyzer out = runJHSDB("jstack", id);
+
+ out.shouldContain("LingeredApp");
+ out.stderrShouldBeEmpty();
+ out.shouldHaveExitValue(0);
+ }
+
+ private static void runJMAP(String id) throws IOException, InterruptedException {
+ OutputAnalyzer out = runJHSDB("jmap", id);
+
+ out.shouldContain("JVM version is");
+ out.stderrShouldBeEmpty();
+ out.shouldHaveExitValue(0);
+ }
+
+ private static void runJINFO(String id) throws IOException, InterruptedException {
+ OutputAnalyzer out = runJHSDB("jinfo", id);
+
+ out.shouldContain("Java System Properties:");
+ out.stderrShouldBeEmpty();
+ out.shouldHaveExitValue(0);
+ }
+
+ private static void runJSNAP(String id) throws IOException, InterruptedException {
+ OutputAnalyzer out = runJHSDB("jsnap", id);
+
+ out.shouldContain("java.vm.name=");
+ out.stderrShouldBeEmpty();
+ out.shouldHaveExitValue(0);
+ }
+
+ private static void runTests(String id, long debuggeePid) throws IOException, InterruptedException {
+ DebugdUtils debugd = new DebugdUtils(id);
+ debugd.attach(debuggeePid);
+
+ try {
+ runJSTACK(id);
+ runJMAP(id);
+ runJINFO(id);
+ runJSNAP(id);
+ } finally {
+ debugd.detach();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ LingeredApp app = null;
+
+ try {
+ app = LingeredApp.startApp();
+ System.out.println("Started LingeredApp with pid " + app.getPid());
+
+ System.out.println("debugd connection test with server id:");
+ runTests("test", app.getPid());
+
+ System.out.println("debugd connection test without server id:");
+ runTests(null, app.getPid());
+ } finally {
+ LingeredApp.stopApp(app);
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdUtils.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import jdk.test.lib.JDKToolLauncher;
+
+
+public class DebugdUtils {
+
+ private static final String GOLDEN = "Debugger attached";
+
+ private final String id;
+
+ private Process debugdProcess;
+
+ public DebugdUtils(String id) {
+ this.id = id;
+ debugdProcess = null;
+ }
+
+ public void attach(long pid) throws IOException {
+ JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+ jhsdbLauncher.addToolArg("debugd");
+ jhsdbLauncher.addToolArg("--pid");
+ jhsdbLauncher.addToolArg(Long.toString(pid));
+ if (id != null) {
+ jhsdbLauncher.addToolArg("--serverid");
+ jhsdbLauncher.addToolArg(id);
+ }
+ debugdProcess = (new ProcessBuilder(jhsdbLauncher.getCommand())).start();
+
+ // Wait until debug server attached
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(debugdProcess.getErrorStream()))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (line.contains(GOLDEN)) {
+ break;
+ }
+ }
+ }
+ }
+
+ public void detach() throws InterruptedException {
+ if (debugdProcess != null) {
+ debugdProcess.destroy();
+ debugdProcess.waitFor();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/TEST.properties Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#
+
+exclusiveAccess.dirs=.
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/followref003.cpp Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/followref003.cpp Mon Jul 22 11:08:27 2019 +0530
@@ -810,7 +810,7 @@
}
break;
- case JVMTI_REFERENCE_ARRAY_ELEMENT:
+ case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
case JVMTI_HEAP_REFERENCE_JNI_GLOBAL:
case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS:
case JVMTI_HEAP_REFERENCE_MONITOR:
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java Mon Jul 22 11:08:27 2019 +0530
@@ -26,6 +26,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.invoke.*;
import java.util.*;
import nsk.share.gc.gp.array.*;
import nsk.share.gc.gp.string.*;
@@ -194,6 +195,36 @@
return eatMemory(stresser, gp, initialFactor, minMemoryChunk, factor, OOM_TYPE.ANY);
}
+ static int numberOfOOMEs = 0;
+
+ /**
+ * Minimal wrapper of the main implementation. Catches any OOM
+ * that might be thrown when rematerializing Objects when deoptimizing.
+ *
+ * It is Important that the impl is not inlined.
+ */
+
+ public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
+ try {
+ // Using a methodhandle invoke of eatMemoryImpl to prevent inlining of it
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(
+ int.class,
+ ExecutionController.class,
+ GarbageProducer.class,
+ long.class,
+ long.class,
+ long.class,
+ OOM_TYPE.class);
+ MethodHandle eat = lookup.findStatic(GarbageUtils.class, "eatMemoryImpl", mt);
+ return (int) eat.invoke(stresser, gp, initialFactor, minMemoryChunk, factor, type);
+ } catch (OutOfMemoryError e) {
+ return numberOfOOMEs++;
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
/**
* Eat memory using given garbage producer.
*
@@ -211,8 +242,9 @@
* @param type of OutOfMemory Exception: Java heap space or Metadata space
* @return number of OOME occured
*/
- public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
- int numberOfOOMEs = 0;
+
+ public static int eatMemoryImpl(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
+ numberOfOOMEs = 0;
try {
byte[] someMemory = new byte[200000]; //200 Kb
try {
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
/*
* @test
- * @bug 6439439 8087303 8174025
+ * @bug 6439439 8087303 8174025 8223291
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true common.prettyprint.PrettyPrintTest
* @run testng/othervm common.prettyprint.PrettyPrintTest
@@ -382,7 +382,6 @@
private Document toXmlDocument(String xmlString) throws Exception {
InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setValidating(true);
DocumentBuilder xmlDocumentBuilder = dbf.newDocumentBuilder();
Document node = xmlDocumentBuilder.parse(xmlInputSource);
return node;
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out Mon Jul 22 11:08:27 2019 +0530
@@ -1,3 +1,1 @@
-<a>
- <![CDATA[ ]]>
-</a>
+<a><![CDATA[ ]]></a>
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,3 @@
-<a>
- <![CDATA[ abc def
+<a><![CDATA[ abc def
line2 &a
- test]]>
-</a>
+ test]]></a>
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out Mon Jul 22 11:08:27 2019 +0530
@@ -1,6 +1,5 @@
<root>
- t
- <![CDATA[ ]]>
+ t<![CDATA[ ]]>
t
<child1/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/ErrorListenerTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package transform;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.xml.sax.InputSource;
+
+/*
+ * @test
+ * @bug 8157830
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm transform.ErrorListenerTest
+ * @summary Verifies that ErrorListeners are handled properly
+ */
+public class ErrorListenerTest {
+
+ static final private String INVALID_STYLESHEET = "xxx";
+ static final private String SYSTEM_ID = "http://openjdk_java_net/xsl/dummy.xsl";
+
+ PrintStream original;
+
+ @BeforeClass
+ public void setUpClass() throws Exception {
+ // save the PrintStream
+ original = System.err;
+ }
+
+ @AfterClass
+ protected void tearDown() throws Exception {
+ // set back to the original
+ System.setErr(original);
+ }
+
+ /**
+ * Verifies that when an ErrorListener is registered, parser errors are passed
+ * onto the listener without other output.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void test() throws Exception {
+ InputStream is = new ByteArrayInputStream(INVALID_STYLESHEET.getBytes());
+ InputSource source = new InputSource(is);
+ source.setSystemId(SYSTEM_ID);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ System.setErr(ps);
+
+ TransformerFactory factory = TransformerFactory.newInstance();
+ factory.setErrorListener(new ErrListener());
+
+ try {
+ factory.newTransformer(new SAXSource(source));
+ } catch (TransformerConfigurationException e) {
+ // nothing
+ }
+
+ // all errors are handled by the ErrorListener, no other output
+ Assert.assertEquals(baos.toString(), "");
+
+ }
+
+ class ErrListener implements ErrorListener {
+
+ @Override
+ public void error(TransformerException exception)
+ throws TransformerException {
+ System.out.println("Correctly handled error: " + exception.getMessage());
+ }
+
+ @Override
+ public void fatalError(TransformerException exception)
+ throws TransformerException {
+ System.out.println("Correctly handled fatal: " + exception.getMessage());
+ }
+
+ @Override
+ public void warning(TransformerException exception)
+ throws TransformerException {
+ System.out.println("Correctly handled warning: " + exception.getMessage());
+ }
+ }
+}
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -24,21 +24,79 @@
package transform;
import java.io.StringReader;
+import java.io.StringWriter;
import java.util.Properties;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.testng.Assert;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
/*
* @test
- * @bug 8219705
+ * @bug 8219705 8223291
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng transform.OutputPropertiesTest
* @summary Verifies the output properties are set correctly
*/
public class OutputPropertiesTest {
+ /*
+ DataProvider: for testing indentation
+ Data: xml, expected result
+ */
+ @DataProvider(name = "Indentation")
+ public Object[][] getData() {
+ String mix = "\n" +
+ " abc\n" +
+ " mix\n" +
+ " xyz\n" +
+ " ";
+ return new Object[][]{
+ {"abc<![CDATA[data]]>xyz", "abcdataxyz"},
+ {"abc<![CDATA[ & ]]>xyz", "abc & xyz"},
+ {"<![CDATA[data]]>", "data"},
+ {"abc<mix>mix</mix>xyz", mix}
+ };
+ }
+
+
+ /**
+ * bug 8223291
+ * Verifies that no extra indentation is added for CDATA.
+ * @param xml the xml content to be tested
+ * @param expected the expected result
+ * @throws Exception
+ */
+ @Test(dataProvider = "Indentation")
+ public void testIndentation(String xml, String expected) throws Exception
+ {
+ StreamSource source = new StreamSource(new StringReader("<foo><bar>" + xml + "</bar></foo>"));
+ StreamResult result = new StreamResult(new StringWriter());
+
+ Transformer tform = TransformerFactory.newInstance().newTransformer();
+ tform.setOutputProperty(OutputKeys.INDENT, "yes");
+ tform.transform(source, result);
+
+ String xml1 = result.getWriter().toString();
+
+ Document document = DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder()
+ .parse(new InputSource(new StringReader(xml1)));
+
+ String resultData = document.getElementsByTagName("bar")
+ .item(0)
+ .getTextContent();
+
+ Assert.assertEquals(resultData, expected);
+ }
+
@Test
public void testOutputProperties() throws Exception {
String xslData = "<?xml version='1.0'?>"
@@ -70,4 +128,5 @@
prNames[i] + ": actual: " + value + ", expected: " + prValues[i]);
}
}
+
}
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/StAXSourceTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/StAXSourceTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
package transform;
+import java.io.ByteArrayInputStream;
import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.StringReader;
import java.io.StringWriter;
@@ -33,6 +34,8 @@
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
@@ -41,14 +44,16 @@
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
import org.testng.Assert;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/*
* @test
- * @bug 8152530 8202426
+ * @bug 8152530 8202426 7148925
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @modules java.xml
* @modules java.xml/com.sun.org.apache.xerces.internal.impl
@@ -62,6 +67,100 @@
*/
@Listeners({jaxp.library.JAXPTestPolicy.class})
public class StAXSourceTest {
+ @DataProvider(name = "xml")
+ public Object[][] getData() throws Exception {
+ // from 6715417, all other data were from 7148925
+ String xmlDT = "<?xml version=\"1.0\" encoding=\"utf-8\"?> "
+ + "<!DOCTYPE bookstore [ "
+ + "<!ELEMENT bookstore (book)*> "
+ + "<!ELEMENT book (title,author,price)> "
+ + "<!ATTLIST book genre CDATA #REQUIRED> "
+ + "<!ELEMENT title (#PCDATA)> "
+ + "<!ELEMENT author (#PCDATA)> "
+ + "<!ELEMENT price (#PCDATA)> ]> "
+ + "<bookstore> "
+ + "<book genre=\"fantasy\" > "
+ + "<title>Oberon's Legacy</title> "
+ + "<author>Corets, Eva</author> "
+ + "<price>5.95</price> "
+ + "</book> "
+ + "</bookstore>";
+ return new Object[][]{
+ {"<root/>"},
+ {"<!DOCTYPE root [<!ENTITY et 'Come Home'>]><root et='&et;'/>"},
+ {"<?xml-stylesheet href='show.xsl' type='text/html'?><root/>"},
+ {"<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?><root/>"},
+ {"<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?>"
+ + "<!DOCTYPE root><root/>"},
+ {"<?xml version='1.0'?><!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]><root/>"},
+ {"<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?>"
+ + "<!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]><root/>"},
+ {xmlDT},
+ };
+ }
+
+ /**
+ * @bug 7148925 6715417
+ *
+ * Verifies that the transformation is successful with a StreamSource.
+ *
+ * @param xml the xml
+ * @throws Exception if the test fails
+ */
+ @Test(dataProvider = "xml")
+ public void parseStreamSource(String xml) throws Exception {
+ Source source = new StreamSource(new StringReader(xml));
+ transform(source, xml);
+ }
+
+ /**
+ * @bug 7148925 6715417
+ *
+ * Verifies that the transformation is successful with a StAXSource created
+ * out of a StreamReader.
+ *
+ * Note that the patch fixes the Exception, but does not include any improvement
+ * over the current. The result may differ from that of StreamSource.
+ *
+ * @param xml the xml
+ * @throws Exception if the test fails
+ */
+ @Test(dataProvider = "xml")
+ public void parseSSSR(String xml) throws Exception {
+ XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
+ XMLStreamReader sr = xif.createXMLStreamReader(new StringReader(xml));
+ StAXSource source = new StAXSource(sr);
+ transform(source, xml);
+ }
+
+ /**
+ * @bug 7148925 6715417
+ *
+ * Verifies that the transformation is successful with a StAXSource created
+ * out of an EventReader.
+ *
+ * Note that the patch fixes the Exception, but does not include any improvement
+ * over the current. The result may differ from that of StreamSource.
+ *
+ * @param xml the xml
+ * @throws Exception if the test fails
+ */
+ @Test(dataProvider = "xml")
+ public void parseSSER(String xml) throws Exception {
+ XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
+ XMLEventReader er = xif.createXMLEventReader(new StringReader(xml));
+ StAXSource source = new StAXSource(er);
+ transform(source, xml);
+ }
+
+ private void transform(Source source, String sourceXml) throws Exception{
+ StringWriter sw = new StringWriter();
+ Result result = new StreamResult(sw);
+ TransformerFactory tf = TransformerFactory.newInstance();
+ tf.newTransformer().transform(source, result);
+ System.out.printf("%n%s:%nSource: %s%nResult: %s%n", source.getClass().getSimpleName(), sourceXml, sw);
+ }
+
/**
* @bug 8202426
* Verifies that a null Attribute type is handled. NPE was thrown before the fix.
--- a/test/jaxp/javax/xml/jaxp/unittest/validation/ValidationTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/validation/ValidationTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -36,11 +36,12 @@
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
+import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/*
* @test
- * @bug 8220818
+ * @bug 8220818 8176447
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm validation.ValidationTest
* @summary Runs validations with schemas and sources
@@ -71,6 +72,17 @@
};
}
+ /*
+ DataProvider: uniqueness
+ */
+ @DataProvider(name = "uniqueness")
+ Object[][] getUniqueData() {
+ return new Object[][]{
+ {"JDK8176447a.xsd", "JDK8176447a.xml"},
+ {"JDK8176447b.xsd", "JDK8176447b.xml"},
+ };
+ }
+
@Test(dataProvider = "invalid", expectedExceptions = SAXParseException.class)
public void testValidateRefType(String xsd, String xml) throws Exception {
validate(xsd, xml);
@@ -81,6 +93,19 @@
validate(xsd, xml);
}
+ /**
+ * @bug 8176447
+ * Verifies that the uniqueness constraint is checked.
+ * @param xsd the XSD
+ * @param xml the XML
+ * @throws Exception expected when the uniqueness constraint is validated
+ * correctly.
+ */
+ @Test(dataProvider = "uniqueness", expectedExceptions = SAXException.class)
+ public void testUnique(String xsd, String xml) throws Exception {
+ validate(xsd, xml);
+ }
+
private void validate(String xsd, String xml) throws Exception {
final SchemaFactory schemaFactory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
@@ -90,4 +115,5 @@
validator.validate(new StreamSource(
new File(getClass().getResource(FILE_PATH + xml).getFile())));
}
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/validation/files/JDK8176447a.xml Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,8 @@
+<test xmlns="http://openjdk_java_net/test.xml"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="JDK8176447a.xsd">
+ <innerObject>
+ <innerInnerObject test-unique-attribute="1" />
+ <innerInnerObject test-unique-attribute="1" />
+ </innerObject>
+</test>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/validation/files/JDK8176447a.xsd Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="http://www.w3.org/1999/xhtml"
+ xmlns:sn="http://openjdk_java_net/test.xml"
+ targetNamespace="http://openjdk_java_net/test.xml" elementFormDefault="qualified">
+ <xsd:element name="test" type="sn:object">
+ <xsd:unique name="testunique">
+ <xsd:selector xpath="sn:innerObject"/>
+ <xsd:field xpath="sn:innerInnerObject/@test-unique-attribute"/>
+ </xsd:unique>
+ </xsd:element>
+ <xsd:complexType name="object">
+ <xsd:sequence>
+ <xsd:element name="innerObject" maxOccurs="unbounded" type="sn:testType" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="testType">
+ <xsd:sequence>
+ <xsd:element name="innerInnerObject" maxOccurs="unbounded" type="sn:testObjectType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="testObjectType">
+ <xsd:attribute use="optional" name="test-unique-attribute" type="xsd:int" />
+ </xsd:complexType>
+</xsd:schema>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/validation/files/JDK8176447b.xml Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="JDK8176447b.xsd">
+ <e>
+ <e1 a1="a" >
+ <e2 a2="a"/>
+ <e2 a2="a"/>
+ </e1>
+ <e1 a1="a">
+ <e2 a2="b"/>
+ <e2 a2="a"/>
+ </e1>
+ </e>
+</root>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/validation/files/JDK8176447b.xsd Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xs:element name="root">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="e" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" name="e1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" name="e2">
+ <xs:complexType>
+ <xs:attribute name="a2" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="a1" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:key name="checkAttrib">
+ <xs:selector xpath=".//e1"/>
+ <xs:field xpath="@a1"/>
+ <xs:field xpath="e2/@a2"/>
+ </xs:key>
+
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
--- a/test/jdk/ProblemList.txt Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/ProblemList.txt Mon Jul 22 11:08:27 2019 +0530
@@ -114,7 +114,6 @@
# jdk_awt
-java/awt/Color/AlphaColorTest.java 8224825 linux-all
java/awt/event/MouseEvent/MouseClickTest/MouseClickTest.java 8168389 windows-all,macosx-all
java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java 8224055 macosx-all
java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java 8168408 windows-all,macosx-all
--- a/test/jdk/com/sun/management/OperatingSystemMXBean/GetCommittedVirtualMemorySize.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/com/sun/management/OperatingSystemMXBean/GetCommittedVirtualMemorySize.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,8 +57,7 @@
// Careful with these values.
private static final long MIN_SIZE_FOR_PASS = 1;
- // Max size for pass dynamically determined below
- private static long max_size_for_pass = Long.MAX_VALUE;
+ private static long MAX_SIZE_FOR_PASS = Long.MAX_VALUE;
private static boolean trace = false;
@@ -67,16 +66,6 @@
trace = true;
}
- // 4934082: On Linux, VM size *can* be larger than total swap
- // size. Linux might not reserve swap memory immediately when
- // a page is mmaped. This means that the reported committed
- // memory size can grow beyond the swap limit.
- long max_size = mbean.getTotalSwapSpaceSize() +
- mbean.getTotalPhysicalMemorySize();
-
- if (max_size > 0) {
- max_size_for_pass = max_size;
- }
long size = mbean.getCommittedVirtualMemorySize();
if (size == -1) {
System.out.println("getCommittedVirtualMemorySize() is not supported");
@@ -88,11 +77,11 @@
size);
}
- if (size < MIN_SIZE_FOR_PASS || size > max_size_for_pass) {
+ if (size < MIN_SIZE_FOR_PASS || size > MAX_SIZE_FOR_PASS) {
throw new RuntimeException("Committed virtual memory size " +
"illegal value: " + size + " bytes " +
"(MIN = " + MIN_SIZE_FOR_PASS + "; " +
- "MAX = " + max_size_for_pass + ")");
+ "MAX = " + MAX_SIZE_FOR_PASS + ")");
}
System.out.println("Test passed.");
--- a/test/jdk/java/awt/Color/AlphaColorTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/awt/Color/AlphaColorTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
/**
* @test
* @key headful
- * @bug 8204931
+ * @bug 8204931 8227392 8224825
* @summary test alpha colors are blended with background.
*/
@@ -73,8 +73,14 @@
static Frame frame;
private static void createAndShowGUI() {
- frame = new Frame("Alpha Color Test");
- frame.setBackground(Color.black);
+ frame = new Frame("Alpha Color Test") {
+ @Override
+ public void paint(Graphics g) {
+ g.setColor(Color.black);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ super.paint(g);
+ }
+ };
Color color = new Color(255, 255, 255, 127);
frame.add("Center", new AlphaColorTest(color));
frame.pack();
--- a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -28,9 +28,12 @@
* @summary Test uses custom launcher that starts VM using JNI that verifies
* reflection API with null caller class
* @library /test/lib
+ * @requires os.family != "aix"
* @run main/native CallerAccessTest
*/
+// Test disabled on AIX since we cannot invoke the JVM on the primordial thread.
+
import java.io.File;
import java.util.Map;
import jdk.test.lib.Platform;
--- a/test/jdk/java/net/HttpURLConnection/HttpResponseCode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/HttpURLConnection/HttpResponseCode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,14 @@
/**
* @test
* @bug 4473092
+ * @library /test/lib
* @summary Method throws IOException when object should be returned
+ * @run main HttpResponseCode
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true HttpResponseCode
*/
import java.net.*;
import java.io.*;
+import jdk.test.lib.net.URIBuilder;
public class HttpResponseCode implements Runnable {
ServerSocket ss;
@@ -61,14 +65,19 @@
HttpResponseCode() throws Exception {
/* start the server */
- ss = new ServerSocket(0);
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(loopback, 0));
(new Thread(this)).start();
/* establish http connection to server */
- String url = "http://localhost:" +
- Integer.toString(ss.getLocalPort()) +
- "/missing.nothtml";
- URLConnection uc = new URL(url).openConnection();
+ URL url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(ss.getLocalPort())
+ .path("/missing.nothtml")
+ .toURL();
+ URLConnection uc = url.openConnection(Proxy.NO_PROXY);
int respCode1 = ((HttpURLConnection)uc).getResponseCode();
((HttpURLConnection)uc).disconnect();
int respCode2 = ((HttpURLConnection)uc).getResponseCode();
--- a/test/jdk/java/net/HttpURLConnection/HttpURLConWithProxy.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/HttpURLConnection/HttpURLConWithProxy.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,12 @@
/*
* @test
* @bug 8161016
+ * @library /test/lib
* @summary When proxy is set HttpURLConnection should not use DIRECT connection.
* @run main/othervm HttpURLConWithProxy
*/
import java.io.IOException;
+import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
@@ -38,10 +40,11 @@
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
+import jdk.test.lib.net.URIBuilder;
public class HttpURLConWithProxy {
- public static void main(String... arg) {
+ public static void main(String... arg) throws Exception {
// Remove the default nonProxyHosts to use localhost for testing
System.setProperty("http.nonProxyHosts", "");
@@ -51,11 +54,18 @@
ServerSocket ss;
URL url;
URLConnection con;
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ InetSocketAddress address = new InetSocketAddress(loopback, 0);
// Test1: using Proxy set by System Property:
try {
- ss = new ServerSocket(0);
- url = new URL("http://localhost:" + ss.getLocalPort());
+ ss = new ServerSocket();
+ ss.bind(address);
+ url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(ss.getLocalPort())
+ .toURL();
con = url.openConnection();
con.setConnectTimeout(10 * 1000);
con.connect();
@@ -69,8 +79,13 @@
MyProxySelector myProxySel = new MyProxySelector();
ProxySelector.setDefault(myProxySel);
try {
- ss = new ServerSocket(0);
- url = new URL("http://localhost:" + ss.getLocalPort());
+ ss = new ServerSocket();
+ ss.bind(address);
+ url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(ss.getLocalPort())
+ .toURL();
con = url.openConnection();
con.setConnectTimeout(10 * 1000);
con.connect();
--- a/test/jdk/java/net/Inet6Address/B6558853.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Inet6Address/B6558853.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,11 @@
/*
* @test
+ * @key intermittent
* @bug 6558853
* @summary getHostAddress() on connections using IPv6 link-local addrs should have zone id
+ * This test needs to bind to the wildcard address and as such is succeptible to
+ * fail intermittently because of port reuse issues.
* @library /test/lib
* @build jdk.test.lib.NetworkConfiguration
* jdk.test.lib.Platform
--- a/test/jdk/java/net/InetAddress/CheckJNI.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/InetAddress/CheckJNI.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,7 @@
}
static void testSocket(InetAddress ia) throws Exception {
- ServerSocket server = new ServerSocket(0);
+ ServerSocket server = new ServerSocket(0, 0, ia);
Socket s = new Socket(ia, server.getLocalPort());
s.close();
server.close();
--- a/test/jdk/java/net/MulticastSocket/NoLoopbackPackets.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/MulticastSocket/NoLoopbackPackets.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
return osname.contains("Windows");
}
+ private static final String MESSAGE = "hello world (" + System.nanoTime() + ")";
public static void main(String[] args) throws Exception {
if (isWindows()) {
System.out.println("The test only run on non-Windows OS. Bye.");
@@ -49,6 +50,7 @@
MulticastSocket msock = null;
List<SocketAddress> failedGroups = new ArrayList<SocketAddress>();
Sender sender = null;
+ Thread senderThread = null;
try {
msock = new MulticastSocket();
int port = msock.getLocalPort();
@@ -69,7 +71,8 @@
}
sender = new Sender(groups);
- new Thread(sender).start();
+ senderThread = new Thread(sender);
+ senderThread.start();
// Now try to receive multicast packets. we should not see any of them
// since we disable loopback mode.
@@ -77,20 +80,41 @@
msock.setSoTimeout(5000); // 5 seconds
byte[] buf = new byte[1024];
+ for (int i = 0; i < buf.length; i++) {
+ buf[i] = (byte) 'z';
+ }
DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
+ byte[] expected = MESSAGE.getBytes();
+ assert expected.length <= buf.length;
for (SocketAddress group : groups) {
+ System.out.println("joining group: " + group);
msock.joinGroup(group, null);
try {
- msock.receive(packet);
+ do {
+ for (int i = 0; i < buf.length; i++) {
+ buf[i] = (byte) 'a';
+ }
+ msock.receive(packet);
+ byte[] data = packet.getData();
+ int len = packet.getLength();
- // it is an error if we receive something
- failedGroups.add(group);
+ if (expected(data, len, expected)) {
+ failedGroups.add(group);
+ break;
+ } else {
+ System.err.println("WARNING: Unexpected packet received from "
+ + group + ": "
+ + len + " bytes");
+ System.err.println("\t as text: " + new String(data, 0, len));
+ }
+ } while (true);
} catch (SocketTimeoutException e) {
// we expect this
+ System.out.println("Received expected exception from " + group + ": " + e);
+ } finally {
+ msock.leaveGroup(group, null);
}
-
- msock.leaveGroup(group, null);
}
} finally {
if (msock != null) try { msock.close(); } catch (Exception e) {}
@@ -98,13 +122,26 @@
sender.stop();
}
}
+ try {
+ if (failedGroups.size() > 0) {
+ System.out.println("We should not receive anything from following groups, but we did:");
+ for (SocketAddress group : failedGroups)
+ System.out.println(group);
+ throw new RuntimeException("test failed.");
+ }
+ } finally {
+ if (senderThread != null) {
+ senderThread.join();
+ }
+ }
+ }
- if (failedGroups.size() > 0) {
- System.out.println("We should not receive anything from following groups, but we did:");
- for (SocketAddress group : failedGroups)
- System.out.println(group);
- throw new RuntimeException("test failed.");
+ static boolean expected(byte[] data, int len, byte[] expected) {
+ if (len != expected.length) return false;
+ for (int i = 0; i < len; i++) {
+ if (data[i] != expected[i]) return false;
}
+ return true;
}
static class Sender implements Runnable {
@@ -116,16 +153,15 @@
}
public void run() {
- byte[] buf = "hello world".getBytes();
+ byte[] buf = MESSAGE.getBytes();
List<DatagramPacket> packets = new ArrayList<DatagramPacket>();
- try {
+ try (MulticastSocket msock = new MulticastSocket()) {
for (SocketAddress group : sendToGroups) {
DatagramPacket packet = new DatagramPacket(buf, buf.length, group);
packets.add(packet);
}
- MulticastSocket msock = new MulticastSocket();
msock.setLoopbackMode(true); // disable loopback mode
while (!stop) {
for (DatagramPacket packet : packets) {
--- a/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,21 @@
/**
* @test
- * @bug 8179559
+ * @bug 8179559 8225239
*/
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
+import java.lang.reflect.Method;
public class NetworkInterfaceRetrievalTests {
public static void main(String[] args) throws Exception {
int checkFailureCount = 0;
+ Method isBound = NetworkInterface.class.getDeclaredMethod("isBoundInetAddress", InetAddress.class);
+ isBound.setAccessible(true);
+
try {
Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces();
@@ -58,6 +62,13 @@
checkFailureCount++;
}
+ // Any bound address should return true when calling isBoundInetAddress
+ if (!((boolean)isBound.invoke(null, addr))) {
+ System.out.println("Retreived net if bound addr " + addr
+ + "NOT shown as bound using NetworkInterface.isBoundAddress "
+ + "***********");
+ checkFailureCount++;
+ }
}
}
--- a/test/jdk/java/net/Socket/AsyncShutdown.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/AsyncShutdown.java Mon Jul 22 11:08:27 2019 +0530
@@ -29,6 +29,8 @@
*/
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
@@ -123,7 +125,7 @@
{
Socket s1 = null;
Socket s2 = null;
- try (ServerSocket ss = new ServerSocket(0)) {
+ try (ServerSocket ss = createBoundServer()) {
s1 = new Socket();
s1.connect(ss.getLocalSocketAddress());
s2 = ss.accept();
@@ -134,4 +136,12 @@
}
}
+ static ServerSocket createBoundServer() throws IOException {
+ ServerSocket ss = new ServerSocket();
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ InetSocketAddress address = new InetSocketAddress(loopback, 0);
+ ss.bind(address);
+ return ss;
+ }
+
}
--- a/test/jdk/java/net/Socket/B6210227.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/B6210227.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,13 +25,17 @@
* @test
* @bug 6210227
* @library /test/lib
- * @summary REGRESSION: Socket.getLocalAddress() returns address of 0.0.0.0 on outbound TCP
+ * @summary REGRESSION: Socket.getLocalAddress() returns address of 0.0.0.0 on outbound TCP.
+ * This test requires binding to the wildcard address.
* @run main B6210227
* @run main/othervm -Djava.net.preferIPv4Stack=true B6210227
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B6210227
*/
import java.util.*;
import java.net.*;
+import java.util.stream.IntStream;
+import java.util.stream.Collectors;
import jdk.test.lib.net.IPSupport;
public class B6210227 {
@@ -42,15 +46,21 @@
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
- byte[] bad = {0,0,0,0};
try {
InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port);
Socket s = new Socket();
s.connect( isa, 1000 );
- InetAddress iaLocal = s.getLocalAddress(); // if this comes back as 0.0. 0.0 this would demonstrate issue
+ InetAddress iaLocal = s.getLocalAddress(); // if this comes back as 0.0.0.0 this would demonstrate issue
String sLocalHostname = iaLocal.getHostName();
- if (Arrays.equals (iaLocal.getAddress(), bad)) {
- throw new RuntimeException ("0.0.0.0 returned");
+ byte[] address = iaLocal.getAddress();
+ if (isWildcard(address)) {
+ if (iaLocal instanceof Inet6Address) {
+ String msg = IntStream.range(0, address.length)
+ .mapToObj(i -> "0").collect(Collectors.joining(":"));
+ throw new RuntimeException(msg + " returned");
+ } else {
+ throw new RuntimeException ("0.0.0.0 returned");
+ }
}
System.out.println("local hostname is "+sLocalHostname );
} catch(Exception e) {
@@ -60,5 +70,11 @@
ss.close();
}
}
+
+ private static boolean isWildcard(byte[] bytes) {
+ for (int i = 0; i < bytes.length ; i++) {
+ if (bytes[i] != 0) return false;
+ }
+ return true;
+ }
}
-
--- a/test/jdk/java/net/Socket/InheritTimeout.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/InheritTimeout.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,10 +56,11 @@
}
InheritTimeout() throws Exception {
- ServerSocket ss = new ServerSocket(0);
+ InetAddress ia = InetAddress.getLocalHost();
+ ServerSocket ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(ia, 0));
ss.setSoTimeout(1000);
- InetAddress ia = InetAddress.getLocalHost();
InetSocketAddress isa =
new InetSocketAddress(ia, ss.getLocalPort());
--- a/test/jdk/java/net/Socket/LinkLocal.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/LinkLocal.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,8 @@
* Create ServerSocket on wildcard address and then
* try to connect Socket to link-local address.
*/
- ServerSocket ss = new ServerSocket(0);
+ ServerSocket ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(ia, 0));
Socket s = new Socket();
try {
@@ -87,7 +88,7 @@
}
DatagramSocket ds1 = new DatagramSocket();
- DatagramSocket ds2 = new DatagramSocket();
+ DatagramSocket ds2 = new DatagramSocket(0, ia);
try {
byte b[] = "Hello".getBytes();
--- a/test/jdk/java/net/Socket/ReadTimeout.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/ReadTimeout.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,8 @@
int tout = 1000;
sin = InetAddress.getLocalHost();
- srv = new ServerSocket(port);
+ srv = new ServerSocket();
+ srv.bind(new InetSocketAddress(sin, 0));
port = srv.getLocalPort();
soc = new Socket(sin, port);
soc1 = srv.accept();
--- a/test/jdk/java/net/Socket/ShutdownInput.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/ShutdownInput.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,9 +47,9 @@
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
- InetAddress iaddr = InetAddress.getLocalHost();
+ InetAddress iaddr = InetAddress.getLoopbackAddress();
- try ( ServerSocket ss = new ServerSocket(0);
+ try (ServerSocket ss = new ServerSocket(0, 0, iaddr);
Socket s1 = new Socket(iaddr, ss.getLocalPort());
Socket s2 = ss.accept() ) {
@@ -57,7 +57,8 @@
}
// check the NIO socket adapter
- try (ServerSocketChannel sc = ServerSocketChannel.open().bind(null);
+ InetSocketAddress socketAddress = new InetSocketAddress(iaddr, 0);
+ try (ServerSocketChannel sc = ServerSocketChannel.open().bind(socketAddress);
SocketChannel s1 = SocketChannel.open(
new InetSocketAddress(iaddr, sc.socket().getLocalPort()));
SocketChannel s2 = sc.accept() ) {
--- a/test/jdk/java/net/Socket/asyncClose/BrokenPipe.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/Socket/asyncClose/BrokenPipe.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,7 @@
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
- ServerSocket ss = new ServerSocket(0);
+ ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLocalHost());
Socket client = new Socket(InetAddress.getLocalHost(),
ss.getLocalPort());
Socket server = ss.accept();
--- a/test/jdk/java/net/SocketInputStream/SocketTimeout.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/SocketInputStream/SocketTimeout.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,8 @@
ServerSocket srv = null;
int port = 0;
- srv = new ServerSocket(0);
+ srv = new ServerSocket();
+ srv.bind(new InetSocketAddress(sin, 0));
port = srv.getLocalPort();
soc = new Socket(sin, port);
soc1 = srv.accept();
--- a/test/jdk/java/net/URLConnection/ChunkedEncoding.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/URLConnection/ChunkedEncoding.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,9 +22,10 @@
*/
/**
- *
+ * @test
* @bug 4333920
* @bug 4394548
+ * @library /test/lib
* @summary Check that chunked encoding response doesn't cause
* getInputStream to block until last chunk arrives.
* Also regression against NPE in ChunkedInputStream.
@@ -32,6 +33,7 @@
import java.net.*;
import java.io.*;
import java.util.Random;
+import jdk.test.lib.net.URIBuilder;
public class ChunkedEncoding implements Runnable {
@@ -115,6 +117,11 @@
out.print("\r\n");
out.flush();
+ /*
+ * Sleep added to avoid connection reset
+ * on the client side
+ */
+ Thread.sleep(1000);
s.close();
ss.close();
} catch (Exception e) {
@@ -125,15 +132,17 @@
ChunkedEncoding() throws Exception {
/* start the server */
- ss = new ServerSocket(0);
+ ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
(new Thread(this)).start();
-
/* establish http connection to server */
- String uri = "http://localhost:" +
- Integer.toString(ss.getLocalPort()) +
- "/foo";
- URL url = new URL(uri);
- HttpURLConnection http = (HttpURLConnection)url.openConnection();
+ URL url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(ss.getLocalPort())
+ .path("/foo")
+ .toURL();
+ HttpURLConnection http = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
/*
* Server should only send headers if TE:trailers
--- a/test/jdk/java/net/URLConnection/GetResponseCode.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/URLConnection/GetResponseCode.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,14 +22,17 @@
*/
/**
- *
+ * @test
* @bug 4191815
+ * @library /test/lib
* @summary Check that getResponseCode doesn't throw exception if http
* respone code is >= 400.
*/
import java.net.*;
import java.io.*;
+import jdk.test.lib.net.URIBuilder;
+
public class GetResponseCode implements Runnable {
ServerSocket ss;
@@ -56,6 +59,11 @@
out.print("</HTML>");
out.flush();
+ /*
+ * Sleep added to avoid connection reset
+ * on the client side
+ */
+ Thread.sleep(1000);
s.close();
ss.close();
} catch (Exception e) {
@@ -66,16 +74,19 @@
GetResponseCode() throws Exception {
/* start the server */
- ss = new ServerSocket(0);
+ ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
(new Thread(this)).start();
/* establish http connection to server */
- String uri = "http://localhost:" +
- Integer.toString(ss.getLocalPort()) +
- "/missing.nothtml";
- URL url = new URL(uri);
+ URL url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(ss.getLocalPort())
+ .path("/missing.nohtml")
+ .toURL();
- HttpURLConnection http = (HttpURLConnection)url.openConnection();
+ HttpURLConnection http = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
int respCode = http.getResponseCode();
--- a/test/jdk/java/net/URLConnection/SetIfModifiedSince.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/URLConnection/SetIfModifiedSince.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/* @test
* @bug 4397096
+ * @library /test/lib
* @run main/othervm SetIfModifiedSince
* @summary setIfModifiedSince() of HttpURLConnection sets invalid date of default locale
*/
@@ -31,7 +32,10 @@
import java.io.*;
import java.util.*;
+import jdk.test.lib.net.URIBuilder;
+
public class SetIfModifiedSince {
+ static volatile boolean successfulHeaderCheck = false;
static class XServer extends Thread {
ServerSocket srv;
@@ -66,28 +70,42 @@
break;
}
}
+ successfulHeaderCheck = true;
s.close ();
srv.close (); // or else the HTTPURLConnection will retry
} catch (IOException e) {}
}
}
- public static void main (String[] args) {
+ public static void main(String[] args) throws Exception {
Locale reservedLocale = Locale.getDefault();
try {
Locale.setDefault(Locale.JAPAN);
- ServerSocket serversocket = new ServerSocket (0);
+ ServerSocket serversocket = new ServerSocket();
+ serversocket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
int port = serversocket.getLocalPort ();
XServer server = new XServer (serversocket);
server.start ();
Thread.sleep (2000);
- URL url = new URL ("http://localhost:"+port+"/index.html");
- URLConnection urlc = url.openConnection ();
+ URL url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(port)
+ .path("/index.html")
+ .toURLUnchecked();
+ URLConnection urlc = url.openConnection(Proxy.NO_PROXY);
urlc.setIfModifiedSince (10000000);
InputStream is = urlc.getInputStream ();
- int i=0, c;
- Thread.sleep (5000);
- } catch (Exception e) {
+ int i = 0, c;
+ Thread.sleep(5000);
+ if (!successfulHeaderCheck) {
+ throw new RuntimeException("Header check was unsuccessful");
+ }
+ } catch (SocketException ce) {
+ if (!successfulHeaderCheck) {
+ throw ce;
+ }
+ System.out.println("ConnectionException expected on successful check of If-modified-since header");
} finally {
// restore the reserved locale
Locale.setDefault(reservedLocale);
--- a/test/jdk/java/net/URLPermission/URLTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/URLPermission/URLTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -276,7 +276,9 @@
}
static class CustomPolicy extends Policy {
+ static final Policy DEFAULT_POLICY = Policy.getPolicy();
final PermissionCollection perms = new Permissions();
+
CustomPolicy(Permission... permissions) {
java.util.Arrays.stream(permissions).forEach(perms::add);
@@ -301,7 +303,7 @@
}
public boolean implies(ProtectionDomain domain, Permission perm) {
- return perms.implies(perm);
+ return perms.implies(perm) || DEFAULT_POLICY.implies(domain, perm);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersFromPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Flow.Publisher;
+import java.util.stream.Stream;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersFromPublisher
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ public BodyPublishersFromPublisher() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ Stream<ByteBuffer> buffers =
+ Stream.generate(() -> S.bufferOfNRandomBytes(1024))
+ .limit(nElements);
+ Publisher<ByteBuffer> pub = S.publisherOfStream(buffers);
+ return BodyPublishers.fromPublisher(pub);
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return BodyPublishers.fromPublisher(S.newErroredPublisher());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersNoBody.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Flow.Publisher;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersNoBody
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ public BodyPublishersNoBody() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ return BodyPublishers.noBody();
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return null;
+ }
+
+ @Override
+ public long maxElementsFromPublisher() {
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArray.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Flow.Publisher;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersOfByteArray
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ private static final int ELEMENT_SIZE = 16 * 1024;
+
+ public BodyPublishersOfByteArray() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ byte[] b = S.arrayOfNRandomBytes(nElements * ELEMENT_SIZE);
+ return BodyPublishers.ofByteArray(b);
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return null;
+ }
+
+ @Override
+ public long maxElementsFromPublisher() {
+ return 21;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArrays.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.concurrent.Flow.Publisher;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersOfByteArrays
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ private static final int ELEMENT_SIZE = 16 * 1024;
+
+ public BodyPublishersOfByteArrays() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ byte[] bytes = S.arrayOfNRandomBytes(ELEMENT_SIZE);
+ return BodyPublishers.ofByteArrays(
+ Collections.nCopies((int) nElements, bytes));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfFile.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.Flow.Publisher;
+import java.util.concurrent.atomic.AtomicLong;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersOfFile
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ private static final int ELEMENT_SIZE = 16 * 1024;
+ private static final AtomicLong UNIQUE_NUMBERS = new AtomicLong();
+
+ public BodyPublishersOfFile() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ try {
+ Path f = createFile(nElements * ELEMENT_SIZE);
+ return BodyPublishers.ofFile(f);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private static Path createFile(long nBytes) throws IOException {
+ String name = "f" + UNIQUE_NUMBERS.getAndIncrement();
+ Path f = Files.createFile(Path.of(name));
+ return Files.write(f, S.arrayOfNRandomBytes(nBytes));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return null;
+ }
+
+ @Override
+ public long maxElementsFromPublisher() {
+ return 21;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfInputStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.io.InputStream;
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Flow.Publisher;
+import java.util.function.Supplier;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersOfInputStream
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ public BodyPublishersOfInputStream() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ Supplier<InputStream> s = () -> S.inputStreamOfNReads((int) nElements);
+ return BodyPublishers.ofInputStream(s);
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfSubByteArray.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Flow.Publisher;
+
+/* See TckDriver.java for more information */
+public class BodyPublishersOfSubByteArray
+ extends FlowPublisherVerification<ByteBuffer> {
+
+ private static final int ELEMENT_SIZE = 16 * 1024;
+
+ public BodyPublishersOfSubByteArray() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFlowPublisher(long nElements) {
+ int prefixLen = S.randomIntUpTo(13);
+ int postfixLen = S.randomIntUpTo(17);
+ byte[] b = S.arrayOfNRandomBytes(nElements * ELEMENT_SIZE);
+ byte[] contents = new byte[prefixLen + b.length + postfixLen];
+ System.arraycopy(b, 0, contents, prefixLen, b.length);
+ return BodyPublishers.ofByteArray(contents, prefixLen, b.length);
+ }
+
+ @Override
+ public Publisher<ByteBuffer> createFailedFlowPublisher() {
+ return null;
+ }
+
+ @Override
+ public long maxElementsFromPublisher() {
+ return 21;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersBuffering.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersBuffering
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersBuffering() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.buffering(BodySubscribers.discarding(),
+ S.randomIntUpTo(1024) + 1);
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersDiscarding.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersDiscarding
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersDiscarding() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.discarding();
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromLineSubscriber.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersFromLineSubscriber
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersFromLineSubscriber() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.fromLineSubscriber(
+ S.nonCompliantSubscriber());
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.scatterBuffer(
+ S.bufferOfNRandomASCIIBytes(element % 17));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromSubscriber.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersFromSubscriber
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersFromSubscriber() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ Subscriber<List<ByteBuffer>> sub = S.nonCompliantSubscriber();
+ return BodySubscribers.fromSubscriber(sub);
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.scatterBuffer(
+ S.bufferOfNRandomASCIIBytes(element % 17));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersMapping.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersMapping
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersMapping() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.mapping(BodySubscribers.ofByteArray(),
+ bytes -> bytes.length);
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArray.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfByteArray
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfByteArray() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofByteArray();
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArrayConsumer.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfByteArrayConsumer
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfByteArrayConsumer() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofByteArrayConsumer(bytes -> { });
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfFile.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfFile
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfFile() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofFile(Path.of("f1.bin"));
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfInputStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfInputStream
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfInputStream() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofInputStream();
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfLines.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfLines
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfLines() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofLines(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.scatterBuffer(
+ S.bufferOfNRandomASCIIBytes(element % 17));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscriber;
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Flow.Publisher;
+import java.util.concurrent.Flow.Subscriber;
+import java.util.concurrent.Flow.Subscription;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfPublisher
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfPublisher() {
+ super(new TestEnvironment(450L));
+ }
+
+ /* The reason for overriding this method is that BodySubscribers.ofPublisher
+ is somewhat tricky. It is not an independent Subscriber, but rather
+ an adaptor from Subscriber to Publisher. Until the Subscriber that
+ subscribed to that resulting Publisher requests anything, nothing
+ happens. */
+ @Override
+ public void triggerFlowRequest(
+ Subscriber<? super List<ByteBuffer>> subscriber)
+ {
+ BodySubscriber<Publisher<List<ByteBuffer>>> sub =
+ (BodySubscriber<Publisher<List<ByteBuffer>>>) subscriber;
+ CompletionStage<Publisher<List<ByteBuffer>>> body = sub.getBody();
+ Publisher<List<ByteBuffer>> pub = body.toCompletableFuture().join();
+ pub.subscribe(new Subscriber<>() {
+
+ @Override
+ public void onSubscribe(Subscription subscription) {
+ subscription.request(Integer.MAX_VALUE);
+ }
+
+ @Override public void onNext(List<ByteBuffer> item) { }
+ @Override public void onError(Throwable throwable) { }
+ @Override public void onComplete() { }
+ });
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofPublisher();
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher1.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscriber;
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Flow.Publisher;
+import java.util.concurrent.Flow.Subscriber;
+import java.util.concurrent.Flow.Subscription;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfPublisher1
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfPublisher1() {
+ super(new TestEnvironment(450L));
+ }
+
+ /* The reason for overriding this method is that BodySubscribers.ofPublisher
+ is somewhat tricky. It is not an independent Subscriber, but rather
+ an adaptor from Subscriber to Publisher. Until the Subscriber that
+ subscribed to that resulting Publisher requests anything, nothing
+ happens. */
+ @Override
+ public void triggerFlowRequest(
+ Subscriber<? super List<ByteBuffer>> subscriber)
+ {
+ BodySubscriber<Publisher<List<ByteBuffer>>> sub =
+ (BodySubscriber<Publisher<List<ByteBuffer>>>) subscriber;
+ CompletionStage<Publisher<List<ByteBuffer>>> body = sub.getBody();
+ Publisher<List<ByteBuffer>> pub = body.toCompletableFuture().join();
+ pub.subscribe(new Subscriber<>() {
+
+ Subscription sub;
+
+ @Override
+ public void onSubscribe(Subscription subscription) {
+ (sub = subscription).request(1);
+ }
+
+ @Override public void onNext(List<ByteBuffer> item) {
+ sub.request(1);
+ }
+
+ @Override public void onError(Throwable throwable) { }
+ @Override public void onComplete() { }
+ });
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofPublisher();
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisherPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.net.http.HttpResponse.BodySubscriber;
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Publisher;
+import java.util.stream.Stream;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfPublisherPublisher
+ extends FlowPublisherVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfPublisherPublisher() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<List<ByteBuffer>> createFlowPublisher(long nElements) {
+ BodySubscriber<Publisher<List<ByteBuffer>>> sub =
+ BodySubscribers.ofPublisher();
+ Stream<List<ByteBuffer>> buffers =
+ Stream.generate(() -> S.listOfBuffersFromBufferOfNBytes(1024))
+ .limit(nElements);
+ Publisher<List<ByteBuffer>> pub = S.publisherOfStream(buffers);
+ pub.subscribe(sub);
+ return sub.getBody().toCompletableFuture().join();
+ }
+
+ @Override
+ public Publisher<List<ByteBuffer>> createFailedFlowPublisher() {
+ BodySubscriber<Publisher<List<ByteBuffer>>> sub =
+ BodySubscribers.ofPublisher();
+ Publisher<List<ByteBuffer>> pub = S.newErroredPublisher();
+ pub.subscribe(sub);
+ return sub.getBody().toCompletableFuture().join();
+ }
+
+ @Override
+ public long maxElementsFromPublisher() {
+ return 21;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfString.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersOfString
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersOfString() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ return BodySubscribers.ofString(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.scatterBuffer(
+ S.bufferOfNRandomASCIIBytes(element % 17));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersReplacing.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification;
+
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.Flow.Subscriber;
+
+/* See TckDriver.java for more information */
+public class BodySubscribersReplacing
+ extends FlowSubscriberBlackboxVerification<List<ByteBuffer>> {
+
+ public BodySubscribersReplacing() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Subscriber<List<ByteBuffer>> createFlowSubscriber() {
+ /* it doesn't matter what we are replacing with */
+ return BodySubscribers.replacing(Boolean.TRUE);
+ }
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return S.listOfBuffersFromBufferOfNBytes(element % 17);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/S.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.concurrent.Flow.Publisher;
+import java.util.concurrent.Flow.Subscriber;
+import java.util.concurrent.Flow.Subscription;
+import java.util.stream.Stream;
+
+/*
+ * S for Support.
+ *
+ * Auxiliary methods for tests that check conformance with reactive streams
+ * specification.
+ *
+ * Short name is for the sake of convenience calling this class' static methods.
+ * It could've been called Support or TckSupport, but then we would need to
+ * place this class in its own package so as to use "import static".
+ */
+public class S {
+
+ private static final Random RANDOM = new SecureRandom();
+
+ private S() { }
+
+ public static List<ByteBuffer> listOfBuffersFromBufferOfNBytes(int nBytes) {
+ return scatterBuffer(bufferOfNRandomBytes(nBytes));
+ }
+
+ /*
+ * Spreads the remaining contents of the given byte buffer across a number
+ * of buffers put into a list.
+ */
+ public static List<ByteBuffer> scatterBuffer(ByteBuffer src) {
+ List<ByteBuffer> buffers = new ArrayList<>();
+ while (src.hasRemaining()) {
+ // We do not allow empty buffers ~~~~~~~~~~~~~~~~v
+ int capacity = RANDOM.nextInt(src.remaining()) + 1;
+ ByteBuffer b = ByteBuffer.allocate(capacity);
+ for (int i = 0; i < capacity; i++) {
+ b.put(src.get());
+ }
+ b.flip();
+ buffers.add(b);
+ }
+ return List.copyOf(buffers);
+ }
+
+ public static ByteBuffer bufferOfNRandomBytes(int capacity) {
+ return ByteBuffer.wrap(arrayOfNRandomBytes(capacity));
+ }
+
+ public static byte[] arrayOfNRandomBytes(int nBytes) {
+ byte[] contents = new byte[nBytes];
+ RANDOM.nextBytes(contents);
+ return contents;
+ }
+
+ public static InputStream inputStreamOfNReads(long n) {
+ return new NReadsInputStream(n);
+ }
+
+ /*
+ * Convenience method for testing publishers.
+ */
+ public static byte[] arrayOfNRandomBytes(long nBytes) {
+ return arrayOfNRandomBytes((int) nBytes);
+ }
+
+ public static ByteBuffer bufferOfNRandomASCIIBytes(int capacity) {
+ String alphaNumeric = "abcdefghijklmnopqrstuvwxyz1234567890";
+ StringBuilder builder = new StringBuilder(capacity);
+ for (int i = 0; i < capacity; i++) {
+ int idx = RANDOM.nextInt(alphaNumeric.length());
+ builder.append(alphaNumeric.charAt(idx));
+ }
+ return ByteBuffer.wrap(builder.toString().getBytes(
+ StandardCharsets.US_ASCII));
+ }
+
+ /*
+ * Returns a simple non-compliant Subscriber.
+ *
+ * This Subscriber is useful for testing our adaptors and wrappers, to make
+ * sure they do not delegate RS compliance to the underlying (and foreign to
+ * java.net.http codebase) Subscribers, but rather comply themselves.
+ *
+ * Here's an example:
+ *
+ * public void onSubscribe(Subscription s) {
+ * delegate.onSubscribe(s);
+ * }
+ *
+ * The snippet above cannot be considered a good implementation of a
+ * Subscriber if `delegate` is an unknown Subscriber. In this case the
+ * implementation should independently check all the rules from the RS spec
+ * related to subscribers.
+ */
+ public static <T> Subscriber<T> nonCompliantSubscriber() {
+ return new Subscriber<>() {
+
+ @Override
+ public void onSubscribe(Subscription subscription) {
+ subscription.request(Long.MAX_VALUE);
+ }
+
+ @Override
+ public void onNext(T item) { }
+
+ @Override
+ public void onError(Throwable throwable) { }
+
+ @Override
+ public void onComplete() { }
+ };
+ }
+
+ public static int randomIntUpTo(int bound) {
+ return RANDOM.nextInt(bound);
+ }
+
+ /*
+ * Signals an error to its subscribers immediately after subscription.
+ */
+ public static <T> Publisher<T> newErroredPublisher() {
+ return subscriber -> {
+ subscriber.onSubscribe(new Subscription() {
+ @Override
+ public void request(long n) { }
+
+ @Override
+ public void cancel() { }
+ });
+ subscriber.onError(new IOException());
+ };
+ }
+
+ /*
+ * Publishes the elements obtained from the stream and signals completion.
+ * Can be cancelled, but cannot signal an error.
+ *
+ * This trivial ad-hoc implementation of Publisher was created so as to
+ * publish lists of byte buffers. We can publish ByteBuffer, but we can't
+ * seem to publish List<ByteBuffer> since there's no readily available
+ * publisher of those, nor there's a simple adaptor.
+ */
+ public static <T> Publisher<T> publisherOfStream(Stream<? extends T> stream)
+ {
+ if (stream == null) {
+ throw new NullPointerException();
+ }
+ return new Publisher<T>() {
+ @Override
+ public void subscribe(Subscriber<? super T> subscriber) {
+ if (subscriber == null) {
+ throw new NullPointerException();
+ }
+ Subscription subscription = new Subscription() {
+
+ boolean inOnNext; // recursion control
+ volatile boolean cancelled;
+ long demand;
+ final Iterator<? extends T> supply = stream.iterator();
+
+ @Override
+ public void request(long n) {
+ demand = demand + n < 0 ? Long.MAX_VALUE : demand + n;
+ if (inOnNext) {
+ return;
+ }
+ if (cancelled)
+ return;
+ if (n <= 0) {
+ cancelled = true;
+ subscriber.onError(new IllegalArgumentException(
+ "non-positive subscription request"));
+ return;
+ }
+ while (supply.hasNext() && demand > 0 && !cancelled) {
+ demand--;
+ inOnNext = true;
+ try {
+ T item = supply.next();
+ subscriber.onNext(item);
+ } finally {
+ inOnNext = false;
+ }
+ }
+ if (!supply.hasNext()) {
+ cancelled = true;
+ subscriber.onComplete();
+ }
+ }
+
+ @Override
+ public void cancel() {
+ cancelled = true;
+ }
+ };
+ subscriber.onSubscribe(subscription);
+ }
+ };
+ }
+
+ static final class NReadsInputStream extends InputStream {
+
+ private static final int EOF = -1;
+ private long readsLeft;
+
+ NReadsInputStream(long n) {
+ if (n < 0) {
+ throw new IllegalArgumentException(String.valueOf(n));
+ }
+ this.readsLeft = n;
+ }
+
+ @Override
+ public int read() {
+ if (readsLeft == 0L) {
+ return EOF;
+ }
+ readsLeft--;
+ return S.randomIntUpTo(256);
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) {
+ Objects.checkFromIndexSize(off, len, b.length);
+ // Must return 0 if len == 0,
+ // even if there are no more reads left
+ if (len == 0) {
+ return 0;
+ }
+ if (readsLeft == 0L) {
+ return EOF;
+ }
+ readsLeft--;
+ // At least one byte MUST be read, but we can read
+ // less than `len` bytes
+ int r = RANDOM.nextInt(len) + 1;
+ for (int i = 0; i < r; i++) {
+ b[i] = (byte) randomIntUpTo(256);
+ }
+ return r;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/SPublisherOfStream.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.FlowPublisherVerification;
+
+import java.util.concurrent.Flow.Publisher;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+
+/* See TckDriver.java for more information */
+public class SPublisherOfStream
+ extends FlowPublisherVerification<Long> {
+
+ public SPublisherOfStream() {
+ super(new TestEnvironment(450L));
+ }
+
+ @Override
+ public Publisher<Long> createFlowPublisher(long nElements) {
+ Stream<Long> s = LongStream.range(0, nElements).boxed();
+ return S.publisherOfStream(s);
+ }
+
+ @Override
+ public Publisher<Long> createFailedFlowPublisher() {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/STest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class STest {
+
+ @DataProvider(name = "bufferSizes")
+ public static Object[][] bufferSizes() {
+ return new Object[][]{
+ { 1},
+ { 2},
+ { 3},
+ { 4},
+ {16},
+ {17},
+ };
+ }
+
+ @DataProvider
+ public static Object[][] inputStream() {
+ return new Object[][] {
+ { 0, 1},
+ { 1, 2},
+ { 1, 3},
+ { 1, 4},
+ { 2, 1},
+ { 2, 2},
+ { 2, 3},
+ { 2, 4},
+ { 2, 13},
+ { 3, 1},
+ { 3, 2},
+ { 3, 3},
+ { 3, 4},
+ { 3, 17},
+ { 4, 1},
+ { 4, 2},
+ { 4, 3},
+ { 4, 4},
+ { 4, 5},
+ { 13, 1},
+ { 13, 2},
+ { 13, 13},
+ { 16, 18},
+ { 17, 2},
+ {255, 1},
+ {256, 255},
+ {257, 267},
+ };
+ }
+
+ @Test
+ public void testScatter0() {
+ List<ByteBuffer> buffers = S.scatterBuffer(
+ ByteBuffer.allocate(0));
+ assertEquals(buffers.size(), 0);
+ }
+
+ @Test(dataProvider = "bufferSizes")
+ public void testScatterN(int n) {
+ final ByteBuffer src = S.bufferOfNRandomBytes(n);
+ final int srcLength = src.remaining();
+ ByteBuffer copy = ByteBuffer.wrap(Arrays.copyOf(src.array(),
+ src.array().length));
+ List<ByteBuffer> buffers = S.scatterBuffer(src);
+ int m = 0;
+ for (ByteBuffer b : buffers) {
+ m += b.remaining();
+ while (b.hasRemaining() & copy.hasRemaining()) {
+ assertEquals(b.get(), copy.get());
+ }
+ }
+ assertEquals(m, srcLength);
+ }
+
+ @Test(dataProvider = "inputStream")
+ public void testInputStreamOfNReads(int n, int capacity) throws IOException {
+ InputStream s = S.inputStreamOfNReads(n);
+ int count = 0;
+ byte[] b = new byte[capacity];
+ while (s.read(b) != -1) {
+ count++;
+ }
+ assertEquals(count, n);
+ assertTrue(s.read() == -1);
+ assertTrue(s.read(b) == -1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/TckDriver.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8226602
+ * @summary Tests convenience reactive primitives with RS TCK
+ *
+ * @library ../reactivestreams-tck
+ * @build S
+ *
+ * @compile -encoding UTF-8 SPublisherOfStream.java
+ *
+ * @compile -encoding UTF-8 BodyPublishersFromPublisher.java
+ * @compile -encoding UTF-8 BodyPublishersNoBody.java
+ * @compile -encoding UTF-8 BodyPublishersOfByteArray.java
+ * @compile -encoding UTF-8 BodyPublishersOfByteArrays.java
+ * @compile -encoding UTF-8 BodyPublishersOfFile.java
+ * @compile -encoding UTF-8 BodyPublishersOfInputStream.java
+ * @compile -encoding UTF-8 BodyPublishersOfSubByteArray.java
+ *
+ * @compile -encoding UTF-8 BodySubscribersBuffering.java
+ * @compile -encoding UTF-8 BodySubscribersDiscarding.java
+ * @compile -encoding UTF-8 BodySubscribersFromLineSubscriber.java
+ * @compile -encoding UTF-8 BodySubscribersFromSubscriber.java
+ * @compile -encoding UTF-8 BodySubscribersMapping.java
+ * @compile -encoding UTF-8 BodySubscribersOfByteArray.java
+ * @compile -encoding UTF-8 BodySubscribersOfByteArrayConsumer.java
+ * @compile -encoding UTF-8 BodySubscribersOfFile.java
+ * @compile -encoding UTF-8 BodySubscribersOfInputStream.java
+ * @compile -encoding UTF-8 BodySubscribersOfLines.java
+ * @compile -encoding UTF-8 BodySubscribersOfPublisher.java
+ * @compile -encoding UTF-8 BodySubscribersOfPublisher1.java
+ * @compile -encoding UTF-8 BodySubscribersOfPublisherPublisher.java
+ * @compile -encoding UTF-8 BodySubscribersOfString.java
+ * @compile -encoding UTF-8 BodySubscribersReplacing.java
+ *
+ * @run testng/othervm STest
+ * @run testng/othervm SPublisherOfStream
+ *
+ * @run testng/othervm BodyPublishersFromPublisher
+ * @run testng/othervm BodyPublishersNoBody
+ * @run testng/othervm BodyPublishersOfByteArray
+ * @run testng/othervm BodyPublishersOfByteArrays
+ * @run testng/othervm BodyPublishersOfFile
+ * @run testng/othervm BodyPublishersOfInputStream
+ * @run testng/othervm BodyPublishersOfSubByteArray
+ *
+ * @run testng/othervm BodySubscribersBuffering
+ * @run testng/othervm BodySubscribersDiscarding
+ * @run testng/othervm BodySubscribersFromLineSubscriber
+ * @run testng/othervm BodySubscribersFromSubscriber
+ * @run testng/othervm BodySubscribersMapping
+ * @run testng/othervm BodySubscribersOfByteArray
+ * @run testng/othervm BodySubscribersOfByteArrayConsumer
+ * @run testng/othervm BodySubscribersOfFile
+ * @run testng/othervm BodySubscribersOfInputStream
+ * @run testng/othervm BodySubscribersOfLines
+ * @run testng/othervm BodySubscribersOfPublisher
+ * @run testng/othervm BodySubscribersOfPublisher1
+ * @run testng/othervm BodySubscribersOfPublisherPublisher
+ * @run testng/othervm BodySubscribersOfString
+ * @run testng/othervm BodySubscribersReplacing
+ *
+ * @key randomness
+ */
+public class TckDriver {
+ /*
+ #### General Information
+
+ 1. This JTREG test aggregates multiple TestNG tests. This is because
+ these tests share a common library (reactivestreams-tck), and we don't
+ want this library to be compiled separately for each of those tests.
+
+ 2. Tests that use RS TCK are compiled with the UTF-8 encoding. This is
+ performed for the sake of reactivestreams-tck. We don't want to patch
+ the TCK because of the extra merging work in the future, should we bring
+ update(s) from the RS repo.
+
+ #### Tests
+
+ 1. The purpose of each test should be easily digestible. The name of the
+ test is derived from the very entity the test exercises. For example,
+
+ the BodyPublishersOfFile test exercises the BodyPublisher obtained
+ by calling BodyPublishers.ofFile(Path)
+
+ the BodySubscribersOfFile test exercises the BodySubscriber obtained
+ by calling BodySubscribers.ofFile(Path)
+
+ 2. RS TCK requires PublisherVerification tests to produce publishers
+ capable of emitting a certain number of elements. In order to achieve
+ this, we use some knowledge of the internal workings of our publishers.
+ An example would be a chunk size a publisher uses to deliver a portion
+ of data. Without knowing that it is not possible to guarantee that the
+ publisher will emit a particular number of elements.
+
+ 3. Typically our publishers cannot be created in a known failed state.
+ In this case the corresponding `createFailedFlowPublisher` method
+ returns `null`.
+
+ 4. SubscriberBlackBoxVerification uses the `createElement(int element)`
+ method. Our implementations usually cap the amount of data created by
+ this method, because it's not known beforehand how big the `element`
+ value is. Hence, sometimes there's code like as follows:
+
+ @Override
+ public List<ByteBuffer> createElement(int element) {
+ return scatterBuffer(
+ bufferOfNRandomASCIIBytes(element % 17));
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
+ }
+
+ 5. The amount of testing RS TCK performs on a publisher seems to depend
+ on the number of elements this publisher reports it can emit. Sometimes
+ a code like the following can be seen in the tests:
+
+ @Override public long maxElementsFromPublisher() {
+ return 21;
+ ~~~~~~~~~~~^
+ }
+
+ This magic number is a result of trial and error and seems to unlock
+ most of the tests. Reporting big values (e.g. Long.MAX_VALUE - 1) is
+ not an option for most of our publishers because they require to have
+ all the elements upfront.
+
+ 6. It doesn't seem currently feasible to provide SubscriberWhiteboxVerification
+ tests as a) it's not clear how much better the coverage is and b) it's
+ significantly harder to code that.
+
+ #### S (Support)
+
+ Support utilities are being tested (STest) too.
+ */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/FlowAdapters.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams;
+
+import java.util.concurrent.Flow;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Bridge between Reactive Streams API and the Java 9 {@link java.util.concurrent.Flow} API.
+ */
+public final class FlowAdapters {
+ /** Utility class. */
+ private FlowAdapters() {
+ throw new IllegalStateException("No instances!");
+ }
+
+ /**
+ * Converts a Flow Publisher into a Reactive Streams Publisher.
+ * @param <T> the element type
+ * @param flowPublisher the source Flow Publisher to convert
+ * @return the equivalent Reactive Streams Publisher
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> org.reactivestreams.Publisher<T> toPublisher(
+ Flow.Publisher<? extends T> flowPublisher) {
+ requireNonNull(flowPublisher, "flowPublisher");
+ final org.reactivestreams.Publisher<T> publisher;
+ if (flowPublisher instanceof FlowPublisherFromReactive) {
+ publisher = (org.reactivestreams.Publisher<T>)(((FlowPublisherFromReactive<T>)flowPublisher).reactiveStreams);
+ } else if (flowPublisher instanceof org.reactivestreams.Publisher) {
+ publisher = (org.reactivestreams.Publisher<T>)flowPublisher;
+ } else {
+ publisher = new ReactivePublisherFromFlow<T>(flowPublisher);
+ }
+ return publisher;
+ }
+
+ /**
+ * Converts a Reactive Streams Publisher into a Flow Publisher.
+ * @param <T> the element type
+ * @param reactiveStreamsPublisher the source Reactive Streams Publisher to convert
+ * @return the equivalent Flow Publisher
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Flow.Publisher<T> toFlowPublisher(
+ org.reactivestreams.Publisher<? extends T> reactiveStreamsPublisher
+ ) {
+ requireNonNull(reactiveStreamsPublisher, "reactiveStreamsPublisher");
+ final Flow.Publisher<T> flowPublisher;
+ if (reactiveStreamsPublisher instanceof ReactivePublisherFromFlow) {
+ flowPublisher = (Flow.Publisher<T>)(((ReactivePublisherFromFlow<T>)reactiveStreamsPublisher).flow);
+ } else if (reactiveStreamsPublisher instanceof Flow.Publisher) {
+ flowPublisher = (Flow.Publisher<T>)reactiveStreamsPublisher;
+ } else {
+ flowPublisher = new FlowPublisherFromReactive<T>(reactiveStreamsPublisher);
+ }
+ return flowPublisher;
+ }
+
+ /**
+ * Converts a Flow Processor into a Reactive Streams Processor.
+ * @param <T> the input value type
+ * @param <U> the output value type
+ * @param flowProcessor the source Flow Processor to convert
+ * @return the equivalent Reactive Streams Processor
+ */
+ @SuppressWarnings("unchecked")
+ public static <T, U> org.reactivestreams.Processor<T, U> toProcessor(
+ Flow.Processor<? super T, ? extends U> flowProcessor
+ ) {
+ requireNonNull(flowProcessor, "flowProcessor");
+ final org.reactivestreams.Processor<T, U> processor;
+ if (flowProcessor instanceof FlowToReactiveProcessor) {
+ processor = (org.reactivestreams.Processor<T, U>)(((FlowToReactiveProcessor<T, U>)flowProcessor).reactiveStreams);
+ } else if (flowProcessor instanceof org.reactivestreams.Processor) {
+ processor = (org.reactivestreams.Processor<T, U>)flowProcessor;
+ } else {
+ processor = new ReactiveToFlowProcessor<T, U>(flowProcessor);
+ }
+ return processor;
+ }
+
+ /**
+ * Converts a Reactive Streams Processor into a Flow Processor.
+ * @param <T> the input value type
+ * @param <U> the output value type
+ * @param reactiveStreamsProcessor the source Reactive Streams Processor to convert
+ * @return the equivalent Flow Processor
+ */
+ @SuppressWarnings("unchecked")
+ public static <T, U> Flow.Processor<T, U> toFlowProcessor(
+ org.reactivestreams.Processor<? super T, ? extends U> reactiveStreamsProcessor
+ ) {
+ requireNonNull(reactiveStreamsProcessor, "reactiveStreamsProcessor");
+ final Flow.Processor<T, U> flowProcessor;
+ if (reactiveStreamsProcessor instanceof ReactiveToFlowProcessor) {
+ flowProcessor = (Flow.Processor<T, U>)(((ReactiveToFlowProcessor<T, U>)reactiveStreamsProcessor).flow);
+ } else if (reactiveStreamsProcessor instanceof Flow.Processor) {
+ flowProcessor = (Flow.Processor<T, U>)reactiveStreamsProcessor;
+ } else {
+ flowProcessor = new FlowToReactiveProcessor<T, U>(reactiveStreamsProcessor);
+ }
+ return flowProcessor;
+ }
+
+ /**
+ * Converts a Reactive Streams Subscriber into a Flow Subscriber.
+ * @param <T> the input and output value type
+ * @param reactiveStreamsSubscriber the Reactive Streams Subscriber instance to convert
+ * @return the equivalent Flow Subscriber
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Flow.Subscriber<T> toFlowSubscriber(org.reactivestreams.Subscriber<T> reactiveStreamsSubscriber) {
+ requireNonNull(reactiveStreamsSubscriber, "reactiveStreamsSubscriber");
+ final Flow.Subscriber<T> flowSubscriber;
+ if (reactiveStreamsSubscriber instanceof ReactiveToFlowSubscriber) {
+ flowSubscriber = (Flow.Subscriber<T>)((ReactiveToFlowSubscriber<T>)reactiveStreamsSubscriber).flow;
+ } else if (reactiveStreamsSubscriber instanceof Flow.Subscriber) {
+ flowSubscriber = (Flow.Subscriber<T>)reactiveStreamsSubscriber;
+ } else {
+ flowSubscriber = new FlowToReactiveSubscriber<T>(reactiveStreamsSubscriber);
+ }
+ return flowSubscriber;
+ }
+
+ /**
+ * Converts a Flow Subscriber into a Reactive Streams Subscriber.
+ * @param <T> the input and output value type
+ * @param flowSubscriber the Flow Subscriber instance to convert
+ * @return the equivalent Reactive Streams Subscriber
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> org.reactivestreams.Subscriber<T> toSubscriber(Flow.Subscriber<T> flowSubscriber) {
+ requireNonNull(flowSubscriber, "flowSubscriber");
+ final org.reactivestreams.Subscriber<T> subscriber;
+ if (flowSubscriber instanceof FlowToReactiveSubscriber) {
+ subscriber = (org.reactivestreams.Subscriber<T>)((FlowToReactiveSubscriber<T>)flowSubscriber).reactiveStreams;
+ } else if (flowSubscriber instanceof org.reactivestreams.Subscriber) {
+ subscriber = (org.reactivestreams.Subscriber<T>)flowSubscriber;
+ } else {
+ subscriber = new ReactiveToFlowSubscriber<T>(flowSubscriber);
+ }
+ return subscriber;
+ }
+
+ /**
+ * Wraps a Reactive Streams Subscription and converts the calls to a Flow Subscription.
+ */
+ static final class FlowToReactiveSubscription implements Flow.Subscription {
+ final org.reactivestreams.Subscription reactiveStreams;
+
+ public FlowToReactiveSubscription(org.reactivestreams.Subscription reactive) {
+ this.reactiveStreams = reactive;
+ }
+
+ @Override
+ public void request(long n) {
+ reactiveStreams.request(n);
+ }
+
+ @Override
+ public void cancel() {
+ reactiveStreams.cancel();
+ }
+
+ }
+
+ /**
+ * Wraps a Flow Subscription and converts the calls to a Reactive Streams Subscription.
+ */
+ static final class ReactiveToFlowSubscription implements org.reactivestreams.Subscription {
+ final Flow.Subscription flow;
+
+ public ReactiveToFlowSubscription(Flow.Subscription flow) {
+ this.flow = flow;
+ }
+
+ @Override
+ public void request(long n) {
+ flow.request(n);
+ }
+
+ @Override
+ public void cancel() {
+ flow.cancel();
+ }
+
+
+ }
+
+ /**
+ * Wraps a Reactive Streams Subscriber and forwards methods of the Flow Subscriber to it.
+ * @param <T> the element type
+ */
+ static final class FlowToReactiveSubscriber<T> implements Flow.Subscriber<T> {
+ final org.reactivestreams.Subscriber<? super T> reactiveStreams;
+
+ public FlowToReactiveSubscriber(org.reactivestreams.Subscriber<? super T> reactive) {
+ this.reactiveStreams = reactive;
+ }
+
+ @Override
+ public void onSubscribe(Flow.Subscription subscription) {
+ reactiveStreams.onSubscribe((subscription == null) ? null : new ReactiveToFlowSubscription(subscription));
+ }
+
+ @Override
+ public void onNext(T item) {
+ reactiveStreams.onNext(item);
+ }
+
+ @Override
+ public void onError(Throwable throwable) {
+ reactiveStreams.onError(throwable);
+ }
+
+ @Override
+ public void onComplete() {
+ reactiveStreams.onComplete();
+ }
+
+ }
+
+ /**
+ * Wraps a Flow Subscriber and forwards methods of the Reactive Streams Subscriber to it.
+ * @param <T> the element type
+ */
+ static final class ReactiveToFlowSubscriber<T> implements org.reactivestreams.Subscriber<T> {
+ final Flow.Subscriber<? super T> flow;
+
+ public ReactiveToFlowSubscriber(Flow.Subscriber<? super T> flow) {
+ this.flow = flow;
+ }
+
+ @Override
+ public void onSubscribe(org.reactivestreams.Subscription subscription) {
+ flow.onSubscribe((subscription == null) ? null : new FlowToReactiveSubscription(subscription));
+ }
+
+ @Override
+ public void onNext(T item) {
+ flow.onNext(item);
+ }
+
+ @Override
+ public void onError(Throwable throwable) {
+ flow.onError(throwable);
+ }
+
+ @Override
+ public void onComplete() {
+ flow.onComplete();
+ }
+
+ }
+
+ /**
+ * Wraps a Flow Processor and forwards methods of the Reactive Streams Processor to it.
+ * @param <T> the input type
+ * @param <U> the output type
+ */
+ static final class ReactiveToFlowProcessor<T, U> implements org.reactivestreams.Processor<T, U> {
+ final Flow.Processor<? super T, ? extends U> flow;
+
+ public ReactiveToFlowProcessor(Flow.Processor<? super T, ? extends U> flow) {
+ this.flow = flow;
+ }
+
+ @Override
+ public void onSubscribe(org.reactivestreams.Subscription subscription) {
+ flow.onSubscribe((subscription == null) ? null : new FlowToReactiveSubscription(subscription));
+ }
+
+ @Override
+ public void onNext(T t) {
+ flow.onNext(t);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ flow.onError(t);
+ }
+
+ @Override
+ public void onComplete() {
+ flow.onComplete();
+ }
+
+ @Override
+ public void subscribe(org.reactivestreams.Subscriber<? super U> s) {
+ flow.subscribe((s == null) ? null : new FlowToReactiveSubscriber<U>(s));
+ }
+ }
+
+ /**
+ * Wraps a Reactive Streams Processor and forwards methods of the Flow Processor to it.
+ * @param <T> the input type
+ * @param <U> the output type
+ */
+ static final class FlowToReactiveProcessor<T, U> implements Flow.Processor<T, U> {
+ final org.reactivestreams.Processor<? super T, ? extends U> reactiveStreams;
+
+ public FlowToReactiveProcessor(org.reactivestreams.Processor<? super T, ? extends U> reactive) {
+ this.reactiveStreams = reactive;
+ }
+
+ @Override
+ public void onSubscribe(Flow.Subscription subscription) {
+ reactiveStreams.onSubscribe((subscription == null) ? null : new ReactiveToFlowSubscription(subscription));
+ }
+
+ @Override
+ public void onNext(T t) {
+ reactiveStreams.onNext(t);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ reactiveStreams.onError(t);
+ }
+
+ @Override
+ public void onComplete() {
+ reactiveStreams.onComplete();
+ }
+
+ @Override
+ public void subscribe(Flow.Subscriber<? super U> s) {
+ reactiveStreams.subscribe((s == null) ? null : new ReactiveToFlowSubscriber<U>(s));
+ }
+ }
+
+ /**
+ * Reactive Streams Publisher that wraps a Flow Publisher.
+ * @param <T> the element type
+ */
+ static final class ReactivePublisherFromFlow<T> implements org.reactivestreams.Publisher<T> {
+ final Flow.Publisher<? extends T> flow;
+
+ public ReactivePublisherFromFlow(Flow.Publisher<? extends T> flowPublisher) {
+ this.flow = flowPublisher;
+ }
+
+ @Override
+ public void subscribe(org.reactivestreams.Subscriber<? super T> reactive) {
+ flow.subscribe((reactive == null) ? null : new FlowToReactiveSubscriber<T>(reactive));
+ }
+ }
+
+ /**
+ * Flow Publisher that wraps a Reactive Streams Publisher.
+ * @param <T> the element type
+ */
+ static final class FlowPublisherFromReactive<T> implements Flow.Publisher<T> {
+
+ final org.reactivestreams.Publisher<? extends T> reactiveStreams;
+
+ public FlowPublisherFromReactive(org.reactivestreams.Publisher<? extends T> reactivePublisher) {
+ this.reactiveStreams = reactivePublisher;
+ }
+
+ @Override
+ public void subscribe(Flow.Subscriber<? super T> flow) {
+ reactiveStreams.subscribe((flow == null) ? null : new ReactiveToFlowSubscriber<T>(flow));
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Processor.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams;
+
+/**
+ * A Processor represents a processing stage—which is both a {@link Subscriber}
+ * and a {@link Publisher} and obeys the contracts of both.
+ *
+ * @param <T> the type of element signaled to the {@link Subscriber}
+ * @param <R> the type of element signaled by the {@link Publisher}
+ */
+public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Publisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams;
+
+/**
+ * A {@link Publisher} is a provider of a potentially unbounded number of sequenced elements, publishing them according to
+ * the demand received from its {@link Subscriber}(s).
+ * <p>
+ * A {@link Publisher} can serve multiple {@link Subscriber}s subscribed {@link #subscribe(Subscriber)} dynamically
+ * at various points in time.
+ *
+ * @param <T> the type of element signaled.
+ */
+public interface Publisher<T> {
+
+ /**
+ * Request {@link Publisher} to start streaming data.
+ * <p>
+ * This is a "factory method" and can be called multiple times, each time starting a new {@link Subscription}.
+ * <p>
+ * Each {@link Subscription} will work for only a single {@link Subscriber}.
+ * <p>
+ * A {@link Subscriber} should only subscribe once to a single {@link Publisher}.
+ * <p>
+ * If the {@link Publisher} rejects the subscription attempt or otherwise fails it will
+ * signal the error via {@link Subscriber#onError}.
+ *
+ * @param s the {@link Subscriber} that will consume signals from this {@link Publisher}
+ */
+ public void subscribe(Subscriber<? super T> s);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscriber.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams;
+
+/**
+ * Will receive call to {@link #onSubscribe(Subscription)} once after passing an instance of {@link Subscriber} to {@link Publisher#subscribe(Subscriber)}.
+ * <p>
+ * No further notifications will be received until {@link Subscription#request(long)} is called.
+ * <p>
+ * After signaling demand:
+ * <ul>
+ * <li>One or more invocations of {@link #onNext(Object)} up to the maximum number defined by {@link Subscription#request(long)}</li>
+ * <li>Single invocation of {@link #onError(Throwable)} or {@link Subscriber#onComplete()} which signals a terminal state after which no further events will be sent.
+ * </ul>
+ * <p>
+ * Demand can be signaled via {@link Subscription#request(long)} whenever the {@link Subscriber} instance is capable of handling more.
+ *
+ * @param <T> the type of element signaled.
+ */
+public interface Subscriber<T> {
+ /**
+ * Invoked after calling {@link Publisher#subscribe(Subscriber)}.
+ * <p>
+ * No data will start flowing until {@link Subscription#request(long)} is invoked.
+ * <p>
+ * It is the responsibility of this {@link Subscriber} instance to call {@link Subscription#request(long)} whenever more data is wanted.
+ * <p>
+ * The {@link Publisher} will send notifications only in response to {@link Subscription#request(long)}.
+ *
+ * @param s
+ * {@link Subscription} that allows requesting data via {@link Subscription#request(long)}
+ */
+ public void onSubscribe(Subscription s);
+
+ /**
+ * Data notification sent by the {@link Publisher} in response to requests to {@link Subscription#request(long)}.
+ *
+ * @param t the element signaled
+ */
+ public void onNext(T t);
+
+ /**
+ * Failed terminal state.
+ * <p>
+ * No further events will be sent even if {@link Subscription#request(long)} is invoked again.
+ *
+ * @param t the throwable signaled
+ */
+ public void onError(Throwable t);
+
+ /**
+ * Successful terminal state.
+ * <p>
+ * No further events will be sent even if {@link Subscription#request(long)} is invoked again.
+ */
+ public void onComplete();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscription.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams;
+
+/**
+ * A {@link Subscription} represents a one-to-one lifecycle of a {@link Subscriber} subscribing to a {@link Publisher}.
+ * <p>
+ * It can only be used once by a single {@link Subscriber}.
+ * <p>
+ * It is used to both signal desire for data and cancel demand (and allow resource cleanup).
+ *
+ */
+public interface Subscription {
+ /**
+ * No events will be sent by a {@link Publisher} until demand is signaled via this method.
+ * <p>
+ * It can be called however often and whenever needed—but if the outstanding cumulative demand ever becomes Long.MAX_VALUE or more,
+ * it may be treated by the {@link Publisher} as "effectively unbounded".
+ * <p>
+ * Whatever has been requested can be sent by the {@link Publisher} so only signal demand for what can be safely handled.
+ * <p>
+ * A {@link Publisher} can send less than is requested if the stream ends but
+ * then must emit either {@link Subscriber#onError(Throwable)} or {@link Subscriber#onComplete()}.
+ *
+ * @param n the strictly positive number of elements to requests to the upstream {@link Publisher}
+ */
+ public void request(long n);
+
+ /**
+ * Request the {@link Publisher} to stop sending data and clean up resources.
+ * <p>
+ * Data may still be sent to meet previously signalled demand after calling cancel.
+ */
+ public void cancel();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncIterablePublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.example.unicast;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * AsyncIterablePublisher is an implementation of Reactive Streams `Publisher`
+ * which executes asynchronously, using a provided `Executor` and produces elements
+ * from a given `Iterable` in a "unicast" configuration to its `Subscribers`.
+ *
+ * NOTE: The code below uses a lot of try-catches to show the reader where exceptions can be expected, and where they are forbidden.
+ */
+public class AsyncIterablePublisher<T> implements Publisher<T> {
+ private final static int DEFAULT_BATCHSIZE = 1024;
+
+ private final Iterable<T> elements; // This is our data source / generator
+ private final Executor executor; // This is our thread pool, which will make sure that our Publisher runs asynchronously to its Subscribers
+ private final int batchSize; // In general, if one uses an `Executor`, one should be nice nad not hog a thread for too long, this is the cap for that, in elements
+
+ public AsyncIterablePublisher(final Iterable<T> elements, final Executor executor) {
+ this(elements, DEFAULT_BATCHSIZE, executor);
+ }
+
+ public AsyncIterablePublisher(final Iterable<T> elements, final int batchSize, final Executor executor) {
+ if (elements == null) throw null;
+ if (executor == null) throw null;
+ if (batchSize < 1) throw new IllegalArgumentException("batchSize must be greater than zero!");
+ this.elements = elements;
+ this.executor = executor;
+ this.batchSize = batchSize;
+ }
+
+ @Override
+ public void subscribe(final Subscriber<? super T> s) {
+ // As per rule 1.11, we have decided to support multiple subscribers in a unicast configuration
+ // for this `Publisher` implementation.
+ // As per 2.13, this method must return normally (i.e. not throw)
+ new SubscriptionImpl(s).init();
+ }
+
+ // These represent the protocol of the `AsyncIterablePublishers` SubscriptionImpls
+ static interface Signal {};
+ enum Cancel implements Signal { Instance; };
+ enum Subscribe implements Signal { Instance; };
+ enum Send implements Signal { Instance; };
+ static final class Request implements Signal {
+ final long n;
+ Request(final long n) {
+ this.n = n;
+ }
+ };
+
+ // This is our implementation of the Reactive Streams `Subscription`,
+ // which represents the association between a `Publisher` and a `Subscriber`.
+ final class SubscriptionImpl implements Subscription, Runnable {
+ final Subscriber<? super T> subscriber; // We need a reference to the `Subscriber` so we can talk to it
+ private boolean cancelled = false; // This flag will track whether this `Subscription` is to be considered cancelled or not
+ private long demand = 0; // Here we track the current demand, i.e. what has been requested but not yet delivered
+ private Iterator<T> iterator; // This is our cursor into the data stream, which we will send to the `Subscriber`
+
+ SubscriptionImpl(final Subscriber<? super T> subscriber) {
+ // As per rule 1.09, we need to throw a `java.lang.NullPointerException` if the `Subscriber` is `null`
+ if (subscriber == null) throw null;
+ this.subscriber = subscriber;
+ }
+
+ // This `ConcurrentLinkedQueue` will track signals that are sent to this `Subscription`, like `request` and `cancel`
+ private final ConcurrentLinkedQueue<Signal> inboundSignals = new ConcurrentLinkedQueue<Signal>();
+
+ // We are using this `AtomicBoolean` to make sure that this `Subscription` doesn't run concurrently with itself,
+ // which would violate rule 1.3 among others (no concurrent notifications).
+ private final AtomicBoolean on = new AtomicBoolean(false);
+
+ // This method will register inbound demand from our `Subscriber` and validate it against rule 3.9 and rule 3.17
+ private void doRequest(final long n) {
+ if (n < 1)
+ terminateDueTo(new IllegalArgumentException(subscriber + " violated the Reactive Streams rule 3.9 by requesting a non-positive number of elements."));
+ else if (demand + n < 1) {
+ // As governed by rule 3.17, when demand overflows `Long.MAX_VALUE` we treat the signalled demand as "effectively unbounded"
+ demand = Long.MAX_VALUE; // Here we protect from the overflow and treat it as "effectively unbounded"
+ doSend(); // Then we proceed with sending data downstream
+ } else {
+ demand += n; // Here we record the downstream demand
+ doSend(); // Then we can proceed with sending data downstream
+ }
+ }
+
+ // This handles cancellation requests, and is idempotent, thread-safe and not synchronously performing heavy computations as specified in rule 3.5
+ private void doCancel() {
+ cancelled = true;
+ }
+
+ // Instead of executing `subscriber.onSubscribe` synchronously from within `Publisher.subscribe`
+ // we execute it asynchronously, this is to avoid executing the user code (`Iterable.iterator`) on the calling thread.
+ // It also makes it easier to follow rule 1.9
+ private void doSubscribe() {
+ try {
+ iterator = elements.iterator();
+ if (iterator == null)
+ iterator = Collections.<T>emptyList().iterator(); // So we can assume that `iterator` is never null
+ } catch(final Throwable t) {
+ subscriber.onSubscribe(new Subscription() { // We need to make sure we signal onSubscribe before onError, obeying rule 1.9
+ @Override public void cancel() {}
+ @Override public void request(long n) {}
+ });
+ terminateDueTo(t); // Here we send onError, obeying rule 1.09
+ }
+
+ if (!cancelled) {
+ // Deal with setting up the subscription with the subscriber
+ try {
+ subscriber.onSubscribe(this);
+ } catch(final Throwable t) { // Due diligence to obey 2.13
+ terminateDueTo(new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onSubscribe.", t));
+ }
+
+ // Deal with already complete iterators promptly
+ boolean hasElements = false;
+ try {
+ hasElements = iterator.hasNext();
+ } catch(final Throwable t) {
+ terminateDueTo(t); // If hasNext throws, there's something wrong and we need to signal onError as per 1.2, 1.4,
+ }
+
+ // If we don't have anything to deliver, we're already done, so lets do the right thing and
+ // not wait for demand to deliver `onComplete` as per rule 1.2 and 1.3
+ if (!hasElements) {
+ try {
+ doCancel(); // Rule 1.6 says we need to consider the `Subscription` cancelled when `onComplete` is signalled
+ subscriber.onComplete();
+ } catch(final Throwable t) { // As per rule 2.13, `onComplete` is not allowed to throw exceptions, so we do what we can, and log this.
+ (new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onComplete.", t)).printStackTrace(System.err);
+ }
+ }
+ }
+ }
+
+ // This is our behavior for producing elements downstream
+ private void doSend() {
+ try {
+ // In order to play nice with the `Executor` we will only send at-most `batchSize` before
+ // rescheduing ourselves and relinquishing the current thread.
+ int leftInBatch = batchSize;
+ do {
+ T next;
+ boolean hasNext;
+ try {
+ next = iterator.next(); // We have already checked `hasNext` when subscribing, so we can fall back to testing -after- `next` is called.
+ hasNext = iterator.hasNext(); // Need to keep track of End-of-Stream
+ } catch (final Throwable t) {
+ terminateDueTo(t); // If `next` or `hasNext` throws (they can, since it is user-provided), we need to treat the stream as errored as per rule 1.4
+ return;
+ }
+ subscriber.onNext(next); // Then we signal the next element downstream to the `Subscriber`
+ if (!hasNext) { // If we are at End-of-Stream
+ doCancel(); // We need to consider this `Subscription` as cancelled as per rule 1.6
+ subscriber.onComplete(); // Then we signal `onComplete` as per rule 1.2 and 1.5
+ }
+ } while (!cancelled // This makes sure that rule 1.8 is upheld, i.e. we need to stop signalling "eventually"
+ && --leftInBatch > 0 // This makes sure that we only send `batchSize` number of elements in one go (so we can yield to other Runnables)
+ && --demand > 0); // This makes sure that rule 1.1 is upheld (sending more than was demanded)
+
+ if (!cancelled && demand > 0) // If the `Subscription` is still alive and well, and we have demand to satisfy, we signal ourselves to send more data
+ signal(Send.Instance);
+ } catch(final Throwable t) {
+ // We can only get here if `onNext` or `onComplete` threw, and they are not allowed to according to 2.13, so we can only cancel and log here.
+ doCancel(); // Make sure that we are cancelled, since we cannot do anything else since the `Subscriber` is faulty.
+ (new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onNext or onComplete.", t)).printStackTrace(System.err);
+ }
+ }
+
+ // This is a helper method to ensure that we always `cancel` when we signal `onError` as per rule 1.6
+ private void terminateDueTo(final Throwable t) {
+ cancelled = true; // When we signal onError, the subscription must be considered as cancelled, as per rule 1.6
+ try {
+ subscriber.onError(t); // Then we signal the error downstream, to the `Subscriber`
+ } catch(final Throwable t2) { // If `onError` throws an exception, this is a spec violation according to rule 1.9, and all we can do is to log it.
+ (new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", t2)).printStackTrace(System.err);
+ }
+ }
+
+ // What `signal` does is that it sends signals to the `Subscription` asynchronously
+ private void signal(final Signal signal) {
+ if (inboundSignals.offer(signal)) // No need to null-check here as ConcurrentLinkedQueue does this for us
+ tryScheduleToExecute(); // Then we try to schedule it for execution, if it isn't already
+ }
+
+ // This is the main "event loop" if you so will
+ @Override public final void run() {
+ if(on.get()) { // establishes a happens-before relationship with the end of the previous run
+ try {
+ final Signal s = inboundSignals.poll(); // We take a signal off the queue
+ if (!cancelled) { // to make sure that we follow rule 1.8, 3.6 and 3.7
+
+ // Below we simply unpack the `Signal`s and invoke the corresponding methods
+ if (s instanceof Request)
+ doRequest(((Request)s).n);
+ else if (s == Send.Instance)
+ doSend();
+ else if (s == Cancel.Instance)
+ doCancel();
+ else if (s == Subscribe.Instance)
+ doSubscribe();
+ }
+ } finally {
+ on.set(false); // establishes a happens-before relationship with the beginning of the next run
+ if(!inboundSignals.isEmpty()) // If we still have signals to process
+ tryScheduleToExecute(); // Then we try to schedule ourselves to execute again
+ }
+ }
+ }
+
+ // This method makes sure that this `Subscription` is only running on one Thread at a time,
+ // this is important to make sure that we follow rule 1.3
+ private final void tryScheduleToExecute() {
+ if(on.compareAndSet(false, true)) {
+ try {
+ executor.execute(this);
+ } catch(Throwable t) { // If we can't run on the `Executor`, we need to fail gracefully
+ if (!cancelled) {
+ doCancel(); // First of all, this failure is not recoverable, so we need to follow rule 1.4 and 1.6
+ try {
+ terminateDueTo(new IllegalStateException("Publisher terminated due to unavailable Executor.", t));
+ } finally {
+ inboundSignals.clear(); // We're not going to need these anymore
+ // This subscription is cancelled by now, but letting it become schedulable again means
+ // that we can drain the inboundSignals queue if anything arrives after clearing
+ on.set(false);
+ }
+ }
+ }
+ }
+ }
+
+ // Our implementation of `Subscription.request` sends a signal to the Subscription that more elements are in demand
+ @Override public void request(final long n) {
+ signal(new Request(n));
+ }
+ // Our implementation of `Subscription.cancel` sends a signal to the Subscription that the `Subscriber` is not interested in any more elements
+ @Override public void cancel() {
+ signal(Cancel.Instance);
+ }
+ // The reason for the `init` method is that we want to ensure the `SubscriptionImpl`
+ // is completely constructed before it is exposed to the thread pool, therefor this
+ // method is only intended to be invoked once, and immediately after the constructor has
+ // finished.
+ void init() {
+ signal(Subscribe.Instance);
+ }
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncSubscriber.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.example.unicast;
+
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * AsyncSubscriber is an implementation of Reactive Streams `Subscriber`,
+ * it runs asynchronously (on an Executor), requests one element
+ * at a time, and invokes a user-defined method to process each element.
+ *
+ * NOTE: The code below uses a lot of try-catches to show the reader where exceptions can be expected, and where they are forbidden.
+ */
+public abstract class AsyncSubscriber<T> implements Subscriber<T>, Runnable {
+
+ // Signal represents the asynchronous protocol between the Publisher and Subscriber
+ private static interface Signal {}
+
+ private enum OnComplete implements Signal { Instance; }
+
+ private static class OnError implements Signal {
+ public final Throwable error;
+ public OnError(final Throwable error) { this.error = error; }
+ }
+
+ private static class OnNext<T> implements Signal {
+ public final T next;
+ public OnNext(final T next) { this.next = next; }
+ }
+
+ private static class OnSubscribe implements Signal {
+ public final Subscription subscription;
+ public OnSubscribe(final Subscription subscription) { this.subscription = subscription; }
+ }
+
+ private Subscription subscription; // Obeying rule 3.1, we make this private!
+ private boolean done; // It's useful to keep track of whether this Subscriber is done or not
+ private final Executor executor; // This is the Executor we'll use to be asynchronous, obeying rule 2.2
+
+ // Only one constructor, and it's only accessible for the subclasses
+ protected AsyncSubscriber(Executor executor) {
+ if (executor == null) throw null;
+ this.executor = executor;
+ }
+
+ // Showcases a convenience method to idempotently marking the Subscriber as "done", so we don't want to process more elements
+ // herefor we also need to cancel our `Subscription`.
+ private final void done() {
+ //On this line we could add a guard against `!done`, but since rule 3.7 says that `Subscription.cancel()` is idempotent, we don't need to.
+ done = true; // If `whenNext` throws an exception, let's consider ourselves done (not accepting more elements)
+ if (subscription != null) { // If we are bailing out before we got a `Subscription` there's little need for cancelling it.
+ try {
+ subscription.cancel(); // Cancel the subscription
+ } catch(final Throwable t) {
+ //Subscription.cancel is not allowed to throw an exception, according to rule 3.15
+ (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err);
+ }
+ }
+ }
+
+ // This method is invoked when the OnNext signals arrive
+ // Returns whether more elements are desired or not, and if no more elements are desired,
+ // for convenience.
+ protected abstract boolean whenNext(final T element);
+
+ // This method is invoked when the OnComplete signal arrives
+ // override this method to implement your own custom onComplete logic.
+ protected void whenComplete() { }
+
+ // This method is invoked if the OnError signal arrives
+ // override this method to implement your own custom onError logic.
+ protected void whenError(Throwable error) { }
+
+ private final void handleOnSubscribe(final Subscription s) {
+ if (s == null) {
+ // Getting a null `Subscription` here is not valid so lets just ignore it.
+ } else if (subscription != null) { // If someone has made a mistake and added this Subscriber multiple times, let's handle it gracefully
+ try {
+ s.cancel(); // Cancel the additional subscription to follow rule 2.5
+ } catch(final Throwable t) {
+ //Subscription.cancel is not allowed to throw an exception, according to rule 3.15
+ (new IllegalStateException(s + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err);
+ }
+ } else {
+ // We have to assign it locally before we use it, if we want to be a synchronous `Subscriber`
+ // Because according to rule 3.10, the Subscription is allowed to call `onNext` synchronously from within `request`
+ subscription = s;
+ try {
+ // If we want elements, according to rule 2.1 we need to call `request`
+ // And, according to rule 3.2 we are allowed to call this synchronously from within the `onSubscribe` method
+ s.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time
+ } catch(final Throwable t) {
+ // Subscription.request is not allowed to throw according to rule 3.16
+ (new IllegalStateException(s + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err);
+ }
+ }
+ }
+
+ private final void handleOnNext(final T element) {
+ if (!done) { // If we aren't already done
+ if(subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec
+ // Check for spec violation of 2.1 and 1.09
+ (new IllegalStateException("Someone violated the Reactive Streams rule 1.09 and 2.1 by signalling OnNext before `Subscription.request`. (no Subscription)")).printStackTrace(System.err);
+ } else {
+ try {
+ if (whenNext(element)) {
+ try {
+ subscription.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time
+ } catch(final Throwable t) {
+ // Subscription.request is not allowed to throw according to rule 3.16
+ (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err);
+ }
+ } else {
+ done(); // This is legal according to rule 2.6
+ }
+ } catch(final Throwable t) {
+ done();
+ try {
+ onError(t);
+ } catch(final Throwable t2) {
+ //Subscriber.onError is not allowed to throw an exception, according to rule 2.13
+ (new IllegalStateException(this + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", t2)).printStackTrace(System.err);
+ }
+ }
+ }
+ }
+ }
+
+ // Here it is important that we do not violate 2.2 and 2.3 by calling methods on the `Subscription` or `Publisher`
+ private void handleOnComplete() {
+ if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec
+ // Publisher is not allowed to signal onComplete before onSubscribe according to rule 1.09
+ (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onComplete prior to onSubscribe.")).printStackTrace(System.err);
+ } else {
+ done = true; // Obey rule 2.4
+ whenComplete();
+ }
+ }
+
+ // Here it is important that we do not violate 2.2 and 2.3 by calling methods on the `Subscription` or `Publisher`
+ private void handleOnError(final Throwable error) {
+ if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec
+ // Publisher is not allowed to signal onError before onSubscribe according to rule 1.09
+ (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onError prior to onSubscribe.")).printStackTrace(System.err);
+ } else {
+ done = true; // Obey rule 2.4
+ whenError(error);
+ }
+ }
+
+ // We implement the OnX methods on `Subscriber` to send Signals that we will process asycnhronously, but only one at a time
+
+ @Override public final void onSubscribe(final Subscription s) {
+ // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Subscription` is `null`
+ if (s == null) throw null;
+
+ signal(new OnSubscribe(s));
+ }
+
+ @Override public final void onNext(final T element) {
+ // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `element` is `null`
+ if (element == null) throw null;
+
+ signal(new OnNext<T>(element));
+ }
+
+ @Override public final void onError(final Throwable t) {
+ // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Throwable` is `null`
+ if (t == null) throw null;
+
+ signal(new OnError(t));
+ }
+
+ @Override public final void onComplete() {
+ signal(OnComplete.Instance);
+ }
+
+ // This `ConcurrentLinkedQueue` will track signals that are sent to this `Subscriber`, like `OnComplete` and `OnNext` ,
+ // and obeying rule 2.11
+ private final ConcurrentLinkedQueue<Signal> inboundSignals = new ConcurrentLinkedQueue<Signal>();
+
+ // We are using this `AtomicBoolean` to make sure that this `Subscriber` doesn't run concurrently with itself,
+ // obeying rule 2.7 and 2.11
+ private final AtomicBoolean on = new AtomicBoolean(false);
+
+ @SuppressWarnings("unchecked")
+ @Override public final void run() {
+ if(on.get()) { // establishes a happens-before relationship with the end of the previous run
+ try {
+ final Signal s = inboundSignals.poll(); // We take a signal off the queue
+ if (!done) { // If we're done, we shouldn't process any more signals, obeying rule 2.8
+ // Below we simply unpack the `Signal`s and invoke the corresponding methods
+ if (s instanceof OnNext<?>)
+ handleOnNext(((OnNext<T>)s).next);
+ else if (s instanceof OnSubscribe)
+ handleOnSubscribe(((OnSubscribe)s).subscription);
+ else if (s instanceof OnError) // We are always able to handle OnError, obeying rule 2.10
+ handleOnError(((OnError)s).error);
+ else if (s == OnComplete.Instance) // We are always able to handle OnComplete, obeying rule 2.9
+ handleOnComplete();
+ }
+ } finally {
+ on.set(false); // establishes a happens-before relationship with the beginning of the next run
+ if(!inboundSignals.isEmpty()) // If we still have signals to process
+ tryScheduleToExecute(); // Then we try to schedule ourselves to execute again
+ }
+ }
+ }
+
+ // What `signal` does is that it sends signals to the `Subscription` asynchronously
+ private void signal(final Signal signal) {
+ if (inboundSignals.offer(signal)) // No need to null-check here as ConcurrentLinkedQueue does this for us
+ tryScheduleToExecute(); // Then we try to schedule it for execution, if it isn't already
+ }
+
+ // This method makes sure that this `Subscriber` is only executing on one Thread at a time
+ private final void tryScheduleToExecute() {
+ if(on.compareAndSet(false, true)) {
+ try {
+ executor.execute(this);
+ } catch(Throwable t) { // If we can't run on the `Executor`, we need to fail gracefully and not violate rule 2.13
+ if (!done) {
+ try {
+ done(); // First of all, this failure is not recoverable, so we need to cancel our subscription
+ } finally {
+ inboundSignals.clear(); // We're not going to need these anymore
+ // This subscription is cancelled by now, but letting the Subscriber become schedulable again means
+ // that we can drain the inboundSignals queue if anything arrives after clearing
+ on.set(false);
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/InfiniteIncrementNumberPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.example.unicast;
+
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+
+import org.reactivestreams.Subscription;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Publisher;
+
+public class InfiniteIncrementNumberPublisher extends AsyncIterablePublisher<Integer> {
+ public InfiniteIncrementNumberPublisher(final Executor executor) {
+ super(new Iterable<Integer>() {
+ @Override public Iterator<Integer> iterator() {
+ return new Iterator<Integer>() {
+ private int at = 0;
+ @Override public boolean hasNext() { return true; }
+ @Override public Integer next() { return at++; } // Wraps around on overflow
+ @Override public void remove() { throw new UnsupportedOperationException(); }
+ };
+ }
+ }, executor);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/NumberIterablePublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.example.unicast;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Publisher;
+
+public class NumberIterablePublisher extends AsyncIterablePublisher<Integer> {
+ public NumberIterablePublisher(final int from, final int to, final Executor executor) {
+ super(new Iterable<Integer>() {
+ { if(from > to) throw new IllegalArgumentException("from must be equal or greater than to!"); }
+ @Override public Iterator<Integer> iterator() {
+ return new Iterator<Integer>() {
+ private int at = from;
+ @Override public boolean hasNext() { return at < to; }
+ @Override public Integer next() {
+ if (!hasNext()) return Collections.<Integer>emptyList().iterator().next();
+ else return at++;
+ }
+ @Override public void remove() { throw new UnsupportedOperationException(); }
+ };
+ }
+ }, executor);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/RangePublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.example.unicast;
+
+import org.reactivestreams.*;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * A synchronous implementation of the {@link Publisher} that can
+ * be subscribed to multiple times and each individual subscription
+ * will receive range of monotonically increasing integer values on demand.
+ */
+public final class RangePublisher implements Publisher<Integer> {
+
+ /** The starting value of the range. */
+ final int start;
+
+ /** The number of items to emit. */
+ final int count;
+
+ /**
+ * Constructs a RangePublisher instance with the given start and count values
+ * that yields a sequence of [start, start + count).
+ * @param start the starting value of the range
+ * @param count the number of items to emit
+ */
+ public RangePublisher(int start, int count) {
+ this.start = start;
+ this.count = count;
+ }
+
+ @Override
+ public void subscribe(Subscriber<? super Integer> subscriber) {
+ // As per rule 1.11, we have decided to support multiple subscribers
+ // in a unicast configuration for this `Publisher` implementation.
+
+ // As per rule 1.09, we need to throw a `java.lang.NullPointerException`
+ // if the `Subscriber` is `null`
+ if (subscriber == null) throw null;
+
+ // As per 2.13, this method must return normally (i.e. not throw).
+ try {
+ subscriber.onSubscribe(new RangeSubscription(subscriber, start, start + count));
+ } catch (Throwable ex) {
+ new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 " +
+ "by throwing an exception from onSubscribe.", ex)
+ // When onSubscribe fails this way, we don't know what state the
+ // subscriber is thus calling onError may cause more crashes.
+ .printStackTrace();
+ }
+ }
+
+ /**
+ * A Subscription implementation that holds the current downstream
+ * requested amount and responds to the downstream's request() and
+ * cancel() calls.
+ */
+ static final class RangeSubscription
+ // We are using this `AtomicLong` to make sure that this `Subscription`
+ // doesn't run concurrently with itself, which would violate rule 1.3
+ // among others (no concurrent notifications).
+ // The atomic transition from 0L to N > 0L will ensure this.
+ extends AtomicLong implements Subscription {
+
+ private static final long serialVersionUID = -9000845542177067735L;
+
+ /** The Subscriber we are emitting integer values to. */
+ final Subscriber<? super Integer> downstream;
+
+ /** The end index (exclusive). */
+ final int end;
+
+ /**
+ * The current index and within the [start, start + count) range that
+ * will be emitted as downstream.onNext().
+ */
+ int index;
+
+ /**
+ * Indicates the emission should stop.
+ */
+ volatile boolean cancelled;
+
+ /**
+ * Holds onto the IllegalArgumentException (containing the offending stacktrace)
+ * indicating there was a non-positive request() call from the downstream.
+ */
+ volatile Throwable invalidRequest;
+
+ /**
+ * Constructs a stateful RangeSubscription that emits signals to the given
+ * downstream from an integer range of [start, end).
+ * @param downstream the Subscriber receiving the integer values and the completion signal.
+ * @param start the first integer value emitted, start of the range
+ * @param end the end of the range, exclusive
+ */
+ RangeSubscription(Subscriber<? super Integer> downstream, int start, int end) {
+ this.downstream = downstream;
+ this.index = start;
+ this.end = end;
+ }
+
+ // This method will register inbound demand from our `Subscriber` and
+ // validate it against rule 3.9 and rule 3.17
+ @Override
+ public void request(long n) {
+ // Non-positive requests should be honored with IllegalArgumentException
+ if (n <= 0L) {
+ invalidRequest = new IllegalArgumentException("§3.9: non-positive requests are not allowed!");
+ n = 1;
+ }
+ // Downstream requests are cumulative and may come from any thread
+ for (;;) {
+ long requested = get();
+ long update = requested + n;
+ // As governed by rule 3.17, when demand overflows `Long.MAX_VALUE`
+ // we treat the signalled demand as "effectively unbounded"
+ if (update < 0L) {
+ update = Long.MAX_VALUE;
+ }
+ // atomically update the current requested amount
+ if (compareAndSet(requested, update)) {
+ // if there was no prior request amount, we start the emission loop
+ if (requested == 0L) {
+ emit(update);
+ }
+ break;
+ }
+ }
+ }
+
+ // This handles cancellation requests, and is idempotent, thread-safe and not
+ // synchronously performing heavy computations as specified in rule 3.5
+ @Override
+ public void cancel() {
+ // Indicate to the emission loop it should stop.
+ cancelled = true;
+ }
+
+ void emit(long currentRequested) {
+ // Load fields to avoid re-reading them from memory due to volatile accesses in the loop.
+ Subscriber<? super Integer> downstream = this.downstream;
+ int index = this.index;
+ int end = this.end;
+ int emitted = 0;
+
+ try {
+ for (; ; ) {
+ // Check if there was an invalid request and then report its exception
+ // as mandated by rule 3.9. The stacktrace in it should
+ // help locate the faulty logic in the Subscriber.
+ Throwable invalidRequest = this.invalidRequest;
+ if (invalidRequest != null) {
+ // When we signal onError, the subscription must be considered as cancelled, as per rule 1.6
+ cancelled = true;
+
+ downstream.onError(invalidRequest);
+ return;
+ }
+
+ // Loop while the index hasn't reached the end and we haven't
+ // emitted all that's been requested
+ while (index != end && emitted != currentRequested) {
+ // to make sure that we follow rule 1.8, 3.6 and 3.7
+ // We stop if cancellation was requested.
+ if (cancelled) {
+ return;
+ }
+
+ downstream.onNext(index);
+
+ // Increment the index for the next possible emission.
+ index++;
+ // Increment the emitted count to prevent overflowing the downstream.
+ emitted++;
+ }
+
+ // If the index reached the end, we complete the downstream.
+ if (index == end) {
+ // to make sure that we follow rule 1.8, 3.6 and 3.7
+ // Unless cancellation was requested by the last onNext.
+ if (!cancelled) {
+ // We need to consider this `Subscription` as cancelled as per rule 1.6
+ // Note, however, that this state is not observable from the outside
+ // world and since we leave the loop with requested > 0L, any
+ // further request() will never trigger the loop.
+ cancelled = true;
+
+ downstream.onComplete();
+ }
+ return;
+ }
+
+ // Did the requested amount change while we were looping?
+ long freshRequested = get();
+ if (freshRequested == currentRequested) {
+ // Save where the loop has left off: the next value to be emitted
+ this.index = index;
+ // Atomically subtract the previously requested (also emitted) amount
+ currentRequested = addAndGet(-currentRequested);
+ // If there was no new request in between get() and addAndGet(), we simply quit
+ // The next 0 to N transition in request() will trigger the next emission loop.
+ if (currentRequested == 0L) {
+ break;
+ }
+ // Looks like there were more async requests, reset the emitted count and continue.
+ emitted = 0;
+ } else {
+ // Yes, avoid the atomic subtraction and resume.
+ // emitted != currentRequest in this case and index
+ // still points to the next value to be emitted
+ currentRequested = freshRequested;
+ }
+ }
+ } catch (Throwable ex) {
+ // We can only get here if `onNext`, `onError` or `onComplete` threw, and they
+ // are not allowed to according to 2.13, so we can only cancel and log here.
+ // If `onError` throws an exception, this is a spec violation according to rule 1.9,
+ // and all we can do is to log it.
+
+ // Make sure that we are cancelled, since we cannot do anything else
+ // since the `Subscriber` is faulty.
+ cancelled = true;
+
+ // We can't report the failure to onError as the Subscriber is unreliable.
+ (new IllegalStateException(downstream + " violated the Reactive Streams rule 2.13 by " +
+ "throwing an exception from onNext, onError or onComplete.", ex))
+ .printStackTrace();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/SyncSubscriber.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.example.unicast;
+
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+
+/**
+ * SyncSubscriber is an implementation of Reactive Streams `Subscriber`,
+ * it runs synchronously (on the Publisher's thread) and requests one element
+ * at a time and invokes a user-defined method to process each element.
+ *
+ * NOTE: The code below uses a lot of try-catches to show the reader where exceptions can be expected, and where they are forbidden.
+ */
+public abstract class SyncSubscriber<T> implements Subscriber<T> {
+ private Subscription subscription; // Obeying rule 3.1, we make this private!
+ private boolean done = false;
+
+ @Override public void onSubscribe(final Subscription s) {
+ // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Subscription` is `null`
+ if (s == null) throw null;
+
+ if (subscription != null) { // If someone has made a mistake and added this Subscriber multiple times, let's handle it gracefully
+ try {
+ s.cancel(); // Cancel the additional subscription
+ } catch(final Throwable t) {
+ //Subscription.cancel is not allowed to throw an exception, according to rule 3.15
+ (new IllegalStateException(s + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err);
+ }
+ } else {
+ // We have to assign it locally before we use it, if we want to be a synchronous `Subscriber`
+ // Because according to rule 3.10, the Subscription is allowed to call `onNext` synchronously from within `request`
+ subscription = s;
+ try {
+ // If we want elements, according to rule 2.1 we need to call `request`
+ // And, according to rule 3.2 we are allowed to call this synchronously from within the `onSubscribe` method
+ s.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time
+ } catch(final Throwable t) {
+ // Subscription.request is not allowed to throw according to rule 3.16
+ (new IllegalStateException(s + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err);
+ }
+ }
+ }
+
+ @Override public void onNext(final T element) {
+ if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec
+ (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onNext prior to onSubscribe.")).printStackTrace(System.err);
+ } else {
+ // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `element` is `null`
+ if (element == null) throw null;
+
+ if (!done) { // If we aren't already done
+ try {
+ if (whenNext(element)) {
+ try {
+ subscription.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time
+ } catch (final Throwable t) {
+ // Subscription.request is not allowed to throw according to rule 3.16
+ (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err);
+ }
+ } else {
+ done();
+ }
+ } catch (final Throwable t) {
+ done();
+ try {
+ onError(t);
+ } catch (final Throwable t2) {
+ //Subscriber.onError is not allowed to throw an exception, according to rule 2.13
+ (new IllegalStateException(this + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", t2)).printStackTrace(System.err);
+ }
+ }
+ }
+ }
+ }
+
+ // Showcases a convenience method to idempotently marking the Subscriber as "done", so we don't want to process more elements
+ // herefor we also need to cancel our `Subscription`.
+ private void done() {
+ //On this line we could add a guard against `!done`, but since rule 3.7 says that `Subscription.cancel()` is idempotent, we don't need to.
+ done = true; // If we `whenNext` throws an exception, let's consider ourselves done (not accepting more elements)
+ try {
+ subscription.cancel(); // Cancel the subscription
+ } catch(final Throwable t) {
+ //Subscription.cancel is not allowed to throw an exception, according to rule 3.15
+ (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err);
+ }
+ }
+
+ // This method is left as an exercise to the reader/extension point
+ // Returns whether more elements are desired or not, and if no more elements are desired
+ protected abstract boolean whenNext(final T element);
+
+ @Override public void onError(final Throwable t) {
+ if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec
+ (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onError prior to onSubscribe.")).printStackTrace(System.err);
+ } else {
+ // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Throwable` is `null`
+ if (t == null) throw null;
+ // Here we are not allowed to call any methods on the `Subscription` or the `Publisher`, as per rule 2.3
+ // And anyway, the `Subscription` is considered to be cancelled if this method gets called, as per rule 2.4
+ }
+ }
+
+ @Override public void onComplete() {
+ if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec
+ (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onComplete prior to onSubscribe.")).printStackTrace(System.err);
+ } else {
+ // Here we are not allowed to call any methods on the `Subscription` or the `Publisher`, as per rule 2.3
+ // And anyway, the `Subscription` is considered to be cancelled if this method gets called, as per rule 2.4
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/IdentityProcessorVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,896 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck;
+
+import org.reactivestreams.Processor;
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.tck.TestEnvironment.ManualPublisher;
+import org.reactivestreams.tck.TestEnvironment.ManualSubscriber;
+import org.reactivestreams.tck.TestEnvironment.ManualSubscriberWithSubscriptionSupport;
+import org.reactivestreams.tck.TestEnvironment.Promise;
+import org.reactivestreams.tck.flow.support.Function;
+import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules;
+import org.reactivestreams.tck.flow.support.PublisherVerificationRules;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class IdentityProcessorVerification<T> extends WithHelperPublisher<T>
+ implements SubscriberWhiteboxVerificationRules, PublisherVerificationRules {
+
+ private final TestEnvironment env;
+
+ ////////////////////// DELEGATED TO SPECS //////////////////////
+
+ // for delegating tests
+ private final SubscriberWhiteboxVerification<T> subscriberVerification;
+
+ // for delegating tests
+ private final PublisherVerification<T> publisherVerification;
+
+ ////////////////// END OF DELEGATED TO SPECS //////////////////
+
+ // number of elements the processor under test must be able ot buffer,
+ // without dropping elements. Defaults to `TestEnvironment.TEST_BUFFER_SIZE`.
+ private final int processorBufferSize;
+
+ /**
+ * Test class must specify the expected time it takes for the publisher to
+ * shut itself down when the the last downstream {@code Subscription} is cancelled.
+ *
+ * The processor will be required to be able to buffer {@code TestEnvironment.TEST_BUFFER_SIZE} elements.
+ */
+ @SuppressWarnings("unused")
+ public IdentityProcessorVerification(final TestEnvironment env) {
+ this(env, PublisherVerification.envPublisherReferenceGCTimeoutMillis(), TestEnvironment.TEST_BUFFER_SIZE);
+ }
+
+ /**
+ * Test class must specify the expected time it takes for the publisher to
+ * shut itself down when the the last downstream {@code Subscription} is cancelled.
+ *
+ * The processor will be required to be able to buffer {@code TestEnvironment.TEST_BUFFER_SIZE} elements.
+ *
+ * @param publisherReferenceGCTimeoutMillis used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher.
+ */
+ @SuppressWarnings("unused")
+ public IdentityProcessorVerification(final TestEnvironment env, long publisherReferenceGCTimeoutMillis) {
+ this(env, publisherReferenceGCTimeoutMillis, TestEnvironment.TEST_BUFFER_SIZE);
+ }
+
+ /**
+ * Test class must specify the expected time it takes for the publisher to
+ * shut itself down when the the last downstream {@code Subscription} is cancelled.
+ *
+ * @param publisherReferenceGCTimeoutMillis used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher.
+ * @param processorBufferSize number of elements the processor is required to be able to buffer.
+ */
+ public IdentityProcessorVerification(final TestEnvironment env, long publisherReferenceGCTimeoutMillis, int processorBufferSize) {
+ this.env = env;
+ this.processorBufferSize = processorBufferSize;
+
+ this.subscriberVerification = new SubscriberWhiteboxVerification<T>(env) {
+ @Override
+ public Subscriber<T> createSubscriber(WhiteboxSubscriberProbe<T> probe) {
+ return IdentityProcessorVerification.this.createSubscriber(probe);
+ }
+
+ @Override public T createElement(int element) {
+ return IdentityProcessorVerification.this.createElement(element);
+ }
+
+ @Override
+ public Publisher<T> createHelperPublisher(long elements) {
+ return IdentityProcessorVerification.this.createHelperPublisher(elements);
+ }
+ };
+
+ publisherVerification = new PublisherVerification<T>(env, publisherReferenceGCTimeoutMillis) {
+ @Override
+ public Publisher<T> createPublisher(long elements) {
+ return IdentityProcessorVerification.this.createPublisher(elements);
+ }
+
+ @Override
+ public Publisher<T> createFailedPublisher() {
+ return IdentityProcessorVerification.this.createFailedPublisher();
+ }
+
+ @Override
+ public long maxElementsFromPublisher() {
+ return IdentityProcessorVerification.this.maxElementsFromPublisher();
+ }
+
+ @Override
+ public long boundedDepthOfOnNextAndRequestRecursion() {
+ return IdentityProcessorVerification.this.boundedDepthOfOnNextAndRequestRecursion();
+ }
+
+ @Override
+ public boolean skipStochasticTests() {
+ return IdentityProcessorVerification.this.skipStochasticTests();
+ }
+ };
+ }
+
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a {@link Processor}, which simply forwards all stream elements from its upstream
+ * to its downstream. It must be able to internally buffer the given number of elements.
+ *
+ * @param bufferSize number of elements the processor is required to be able to buffer.
+ */
+ public abstract Processor<T, T> createIdentityProcessor(int bufferSize);
+
+ /**
+ * By implementing this method, additional TCK tests concerning a "failed" publishers will be run.
+ *
+ * The expected behaviour of the {@link Publisher} returned by this method is hand out a subscription,
+ * followed by signalling {@code onError} on it, as specified by Rule 1.9.
+ *
+ * If you want to ignore these additional tests, return {@code null} from this method.
+ */
+ public abstract Publisher<T> createFailedPublisher();
+
+ /**
+ * Override and return lower value if your Publisher is only able to produce a known number of elements.
+ * For example, if it is designed to return at-most-one element, return {@code 1} from this method.
+ *
+ * Defaults to {@code Long.MAX_VALUE - 1}, meaning that the Publisher can be produce a huge but NOT an unbounded number of elements.
+ *
+ * To mark your Publisher will *never* signal an {@code onComplete} override this method and return {@code Long.MAX_VALUE},
+ * which will result in *skipping all tests which require an onComplete to be triggered* (!).
+ */
+ public long maxElementsFromPublisher() {
+ return Long.MAX_VALUE - 1;
+ }
+
+ /**
+ * In order to verify rule 3.3 of the reactive streams spec, this number will be used to check if a
+ * {@code Subscription} actually solves the "unbounded recursion" problem by not allowing the number of
+ * recursive calls to exceed the number returned by this method.
+ *
+ * @see <a href="https://github.com/reactive-streams/reactive-streams-jvm#3.3">reactive streams spec, rule 3.3</a>
+ * @see PublisherVerification#required_spec303_mustNotAllowUnboundedRecursion()
+ */
+ public long boundedDepthOfOnNextAndRequestRecursion() {
+ return 1;
+ }
+
+ /**
+ * Override and return {@code true} in order to skip executing tests marked as {@code Stochastic}.
+ * Stochastic in this case means that the Rule is impossible or infeasible to deterministically verify—
+ * usually this means that this test case can yield false positives ("be green") even if for some case,
+ * the given implementation may violate the tested behaviour.
+ */
+ public boolean skipStochasticTests() {
+ return false;
+ }
+
+ /**
+ * Describes the tested implementation in terms of how many subscribers they can support.
+ * Some tests require the {@code Publisher} under test to support multiple Subscribers,
+ * yet the spec does not require all publishers to be able to do so, thus – if an implementation
+ * supports only a limited number of subscribers (e.g. only 1 subscriber, also known as "no fanout")
+ * you MUST return that number from this method by overriding it.
+ */
+ public long maxSupportedSubscribers() {
+ return Long.MAX_VALUE;
+ }
+
+ /**
+ * Override this method and return {@code true} if the {@link Processor} returned by the
+ * {@link #createIdentityProcessor(int)} coordinates its {@link Subscriber}s
+ * request amounts and only delivers onNext signals if all Subscribers have
+ * indicated (via their Subscription#request(long)) they are ready to receive elements.
+ */
+ public boolean doesCoordinatedEmission() {
+ return false;
+ }
+
+ ////////////////////// TEST ENV CLEANUP /////////////////////////////////////
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ publisherVerification.setUp();
+ subscriberVerification.setUp();
+ }
+
+ ////////////////////// PUBLISHER RULES VERIFICATION ///////////////////////////
+
+ // A Processor
+ // must obey all Publisher rules on its publishing side
+ public Publisher<T> createPublisher(long elements) {
+ final Processor<T, T> processor = createIdentityProcessor(processorBufferSize);
+ final Publisher<T> pub = createHelperPublisher(elements);
+ pub.subscribe(processor);
+ return processor; // we run the PublisherVerification against this
+ }
+
+ @Override @Test
+ public void required_validate_maxElementsFromPublisher() throws Exception {
+ publisherVerification.required_validate_maxElementsFromPublisher();
+ }
+
+ @Override @Test
+ public void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception {
+ publisherVerification.required_validate_boundedDepthOfOnNextAndRequestRecursion();
+ }
+
+ /////////////////////// DELEGATED TESTS, A PROCESSOR "IS A" PUBLISHER //////////////////////
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#4.1
+
+ @Test
+ public void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable {
+ publisherVerification.required_createPublisher1MustProduceAStreamOfExactly1Element();
+ }
+
+ @Test
+ public void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable {
+ publisherVerification.required_createPublisher3MustProduceAStreamOfExactly3Elements();
+ }
+
+ @Override @Test
+ public void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable {
+ publisherVerification.required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements();
+ }
+
+ @Override @Test
+ public void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable {
+ publisherVerification.required_spec102_maySignalLessThanRequestedAndTerminateSubscription();
+ }
+
+ @Override @Test
+ public void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable {
+ publisherVerification.stochastic_spec103_mustSignalOnMethodsSequentially();
+ }
+
+ @Override @Test
+ public void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable {
+ publisherVerification.optional_spec104_mustSignalOnErrorWhenFails();
+ }
+
+ @Override @Test
+ public void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable {
+ publisherVerification.required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates();
+ }
+
+ @Override @Test
+ public void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable {
+ publisherVerification.optional_spec105_emptyStreamMustTerminateBySignallingOnComplete();
+ }
+
+ @Override @Test
+ public void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable {
+ publisherVerification.untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled();
+ }
+
+ @Override @Test
+ public void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable {
+ publisherVerification.required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled();
+ }
+
+ @Override @Test
+ public void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable {
+ publisherVerification.untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled();
+ }
+
+ @Override @Test
+ public void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable {
+ publisherVerification.untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals();
+ }
+
+ @Override @Test
+ public void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable {
+ publisherVerification.untested_spec109_subscribeShouldNotThrowNonFatalThrowable();
+ }
+
+ @Override @Test
+ public void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable {
+ publisherVerification.required_spec109_subscribeThrowNPEOnNullSubscriber();
+ }
+
+ @Override @Test
+ public void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable {
+ publisherVerification.required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe();
+ }
+
+ @Override @Test
+ public void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable {
+ publisherVerification.required_spec109_mustIssueOnSubscribeForNonNullSubscriber();
+ }
+
+ @Override @Test
+ public void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable {
+ publisherVerification.untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice();
+ }
+
+ @Override @Test
+ public void optional_spec111_maySupportMultiSubscribe() throws Throwable {
+ publisherVerification.optional_spec111_maySupportMultiSubscribe();
+ }
+
+ @Override @Test
+ public void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable {
+ publisherVerification.optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals();
+ }
+
+ @Override @Test
+ public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable {
+ publisherVerification.optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne();
+ }
+
+ @Override @Test
+ public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable {
+ publisherVerification.optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront();
+ }
+
+ @Override @Test
+ public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable {
+ publisherVerification.optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected();
+ }
+
+ @Override @Test
+ public void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable {
+ publisherVerification.required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe();
+ }
+
+ @Override @Test
+ public void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable {
+ publisherVerification.required_spec303_mustNotAllowUnboundedRecursion();
+ }
+
+ @Override @Test
+ public void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception {
+ publisherVerification.untested_spec304_requestShouldNotPerformHeavyComputations();
+ }
+
+ @Override @Test
+ public void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception {
+ publisherVerification.untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation();
+ }
+
+ @Override @Test
+ public void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable {
+ publisherVerification.required_spec306_afterSubscriptionIsCancelledRequestMustBeNops();
+ }
+
+ @Override @Test
+ public void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable {
+ publisherVerification.required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops();
+ }
+
+ @Override @Test
+ public void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable {
+ publisherVerification.required_spec309_requestZeroMustSignalIllegalArgumentException();
+ }
+
+ @Override @Test
+ public void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable {
+ publisherVerification.required_spec309_requestNegativeNumberMustSignalIllegalArgumentException();
+ }
+
+ @Override @Test
+ public void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable {
+ publisherVerification.optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage();
+ }
+
+ @Override @Test
+ public void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable {
+ publisherVerification.required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling();
+ }
+
+ @Override @Test
+ public void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable {
+ publisherVerification.required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber();
+ }
+
+ @Override @Test
+ public void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable {
+ publisherVerification.required_spec317_mustSupportAPendingElementCountUpToLongMaxValue();
+ }
+
+ @Override @Test
+ public void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable {
+ publisherVerification.required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue();
+ }
+
+ @Override @Test
+ public void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable {
+ publisherVerification.required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue();
+ }
+
+
+ /**
+ * Asks for a {@code Processor} that supports at least 2 {@code Subscriber}s at once and checks if two {@code Subscriber}s
+ * receive the same items and a terminal {@code Exception}.
+ * <p>
+ * If the {@code Processor} requests and/or emits items only when all of its {@code Subscriber}s have requested,
+ * override {@link #doesCoordinatedEmission()} and return {@code true} to indicate this property.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.4'>1.4</a> with multiple
+ * {@code Subscriber}s.
+ * <p>
+ * The test is not executed if {@link IdentityProcessorVerification#maxSupportedSubscribers()} is less than 2.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Processor} implementation:
+ * <ul>
+ * <li>The {@code TestEnvironment} has large enough timeout specified in case the {@code Processor} has some time-delay behavior.</li>
+ * <li>The {@code Processor} is able to fulfill requests of its {@code Subscriber}s independently of each other's requests or
+ * else override {@link #doesCoordinatedEmission()} and return {@code true} to indicate the test {@code Subscriber}s
+ * both have to request first.</li>
+ * </ul>
+ */
+ @Test
+ public void required_spec104_mustCallOnErrorOnAllItsSubscribersIfItEncountersANonRecoverableError() throws Throwable {
+ optionalMultipleSubscribersTest(2, new Function<Long,TestSetup>() {
+ @Override
+ public TestSetup apply(Long aLong) throws Throwable {
+ return new TestSetup(env, processorBufferSize) {{
+ final ManualSubscriberWithErrorCollection<T> sub1 = new ManualSubscriberWithErrorCollection<T>(env);
+ env.subscribe(processor, sub1);
+
+ final ManualSubscriberWithErrorCollection<T> sub2 = new ManualSubscriberWithErrorCollection<T>(env);
+ env.subscribe(processor, sub2);
+
+ final Exception ex = new RuntimeException("Test exception");
+
+ if (doesCoordinatedEmission()) {
+ sub1.request(1);
+ sub2.request(1);
+
+ expectRequest();
+
+ final T x = sendNextTFromUpstream();
+
+ expectNextElement(sub1, x);
+ expectNextElement(sub2, x);
+
+ sub1.request(1);
+ sub2.request(1);
+ } else {
+ sub1.request(1);
+
+ expectRequest(env.defaultTimeoutMillis(),
+ "If the Processor coordinates requests/emissions when having multiple Subscribers"
+ + " at once, please override doesCoordinatedEmission() to return true in this "
+ + "IdentityProcessorVerification to allow this test to pass.");
+
+ final T x = sendNextTFromUpstream();
+ expectNextElement(sub1, x,
+ "If the Processor coordinates requests/emissions when having multiple Subscribers"
+ + " at once, please override doesCoordinatedEmission() to return true in this "
+ + "IdentityProcessorVerification to allow this test to pass.");
+
+ sub1.request(1);
+
+ // sub1 has received one element, and has one demand pending
+ // sub2 has not yet requested anything
+ }
+ sendError(ex);
+
+ sub1.expectError(ex);
+ sub2.expectError(ex);
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }};
+ }
+ });
+ }
+
+ ////////////////////// SUBSCRIBER RULES VERIFICATION ///////////////////////////
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#4.1
+
+ // A Processor
+ // must obey all Subscriber rules on its consuming side
+ public Subscriber<T> createSubscriber(final SubscriberWhiteboxVerification.WhiteboxSubscriberProbe<T> probe) {
+ final Processor<T, T> processor = createIdentityProcessor(processorBufferSize);
+ processor.subscribe(
+ new Subscriber<T>() {
+ private final Promise<Subscription> subs = new Promise<Subscription>(env);
+
+ @Override
+ public void onSubscribe(final Subscription subscription) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("whiteboxSubscriber::onSubscribe(%s)", subscription));
+ }
+ if (subs.isCompleted()) subscription.cancel(); // the Probe must also pass subscriber verification
+
+ probe.registerOnSubscribe(new SubscriberWhiteboxVerification.SubscriberPuppet() {
+
+ @Override
+ public void triggerRequest(long elements) {
+ subscription.request(elements);
+ }
+
+ @Override
+ public void signalCancel() {
+ subscription.cancel();
+ }
+ });
+ }
+
+ @Override
+ public void onNext(T element) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("whiteboxSubscriber::onNext(%s)", element));
+ }
+ probe.registerOnNext(element);
+ }
+
+ @Override
+ public void onComplete() {
+ if (env.debugEnabled()) {
+ env.debug("whiteboxSubscriber::onComplete()");
+ }
+ probe.registerOnComplete();
+ }
+
+ @Override
+ public void onError(Throwable cause) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("whiteboxSubscriber::onError(%s)", cause));
+ }
+ probe.registerOnError(cause);
+ }
+ });
+
+ return processor; // we run the SubscriberVerification against this
+ }
+
+ ////////////////////// OTHER RULE VERIFICATION ///////////////////////////
+
+ // A Processor
+ // must immediately pass on `onError` events received from its upstream to its downstream
+ @Test
+ public void mustImmediatelyPassOnOnErrorEventsReceivedFromItsUpstreamToItsDownstream() throws Exception {
+ new TestSetup(env, processorBufferSize) {{
+ final ManualSubscriberWithErrorCollection<T> sub = new ManualSubscriberWithErrorCollection<T>(env);
+ env.subscribe(processor, sub);
+
+ final Exception ex = new RuntimeException("Test exception");
+ sendError(ex);
+ sub.expectError(ex); // "immediately", i.e. without a preceding request
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }};
+ }
+
+ /////////////////////// DELEGATED TESTS, A PROCESSOR "IS A" SUBSCRIBER //////////////////////
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#4.1
+
+ @Test
+ public void required_exerciseWhiteboxHappyPath() throws Throwable {
+ subscriberVerification.required_exerciseWhiteboxHappyPath();
+ }
+
+ @Override @Test
+ public void required_spec201_mustSignalDemandViaSubscriptionRequest() throws Throwable {
+ subscriberVerification.required_spec201_mustSignalDemandViaSubscriptionRequest();
+ }
+
+ @Override @Test
+ public void untested_spec202_shouldAsynchronouslyDispatch() throws Exception {
+ subscriberVerification.untested_spec202_shouldAsynchronouslyDispatch();
+ }
+
+ @Override @Test
+ public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable {
+ subscriberVerification.required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete();
+ }
+
+ @Override @Test
+ public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable {
+ subscriberVerification.required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError();
+ }
+
+ @Override @Test
+ public void untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception {
+ subscriberVerification.untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError();
+ }
+
+ @Override @Test
+ public void required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Throwable {
+ subscriberVerification.required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal();
+ }
+
+ @Override @Test
+ public void untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception {
+ subscriberVerification.untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid();
+ }
+
+ @Override @Test
+ public void untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception {
+ subscriberVerification.untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization();
+ }
+
+ @Override @Test
+ public void required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable {
+ subscriberVerification.required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel();
+ }
+
+ @Override @Test
+ public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable {
+ subscriberVerification.required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall();
+ }
+
+ @Override @Test
+ public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable {
+ subscriberVerification.required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall();
+ }
+
+ @Override @Test
+ public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable {
+ subscriberVerification.required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall();
+ }
+
+ @Override @Test
+ public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable {
+ subscriberVerification.required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall();
+ }
+
+ @Override @Test
+ public void untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception {
+ subscriberVerification.untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents();
+ }
+
+ @Override @Test
+ public void untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation() throws Throwable {
+ subscriberVerification.untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation();
+ }
+
+ @Override @Test
+ public void untested_spec213_failingOnSignalInvocation() throws Exception {
+ subscriberVerification.untested_spec213_failingOnSignalInvocation();
+ }
+
+ @Override @Test
+ public void required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ subscriberVerification.required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull();
+ }
+ @Override @Test
+ public void required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ subscriberVerification.required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull();
+ }
+ @Override @Test
+ public void required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ subscriberVerification.required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull();
+ }
+
+ @Override @Test
+ public void untested_spec301_mustNotBeCalledOutsideSubscriberContext() throws Exception {
+ subscriberVerification.untested_spec301_mustNotBeCalledOutsideSubscriberContext();
+ }
+
+ @Override @Test
+ public void required_spec308_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable {
+ subscriberVerification.required_spec308_requestMustRegisterGivenNumberElementsToBeProduced();
+ }
+
+ @Override @Test
+ public void untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception {
+ subscriberVerification.untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber();
+ }
+
+ @Override @Test
+ public void untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception {
+ subscriberVerification.untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError();
+ }
+
+ @Override @Test
+ public void untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception {
+ subscriberVerification.untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists();
+ }
+
+ @Override @Test
+ public void untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception {
+ subscriberVerification.untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError();
+ }
+
+ @Override @Test
+ public void untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception {
+ subscriberVerification.untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber();
+ }
+
+ /////////////////////// ADDITIONAL "COROLLARY" TESTS //////////////////////
+
+ /**
+ * Asks for a {@code Processor} that supports at least 2 {@code Subscriber}s at once and checks requests
+ * from {@code Subscriber}s will eventually lead to requests towards the upstream of the {@code Processor}.
+ * <p>
+ * If the {@code Processor} requests and/or emits items only when all of its {@code Subscriber}s have requested,
+ * override {@link #doesCoordinatedEmission()} and return {@code true} to indicate this property.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.4'>2.1</a> with multiple
+ * {@code Subscriber}s.
+ * <p>
+ * The test is not executed if {@link IdentityProcessorVerification#maxSupportedSubscribers()} is less than 2.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Processor} implementation:
+ * <ul>
+ * <li>The {@code TestEnvironment} has large enough timeout specified in case the {@code Processor} has some time-delay behavior.</li>
+ * <li>The {@code Processor} is able to fulfill requests of its {@code Subscriber}s independently of each other's requests or
+ * else override {@link #doesCoordinatedEmission()} and return {@code true} to indicate the test {@code Subscriber}s
+ * both have to request first.</li>
+ * </ul>
+ */
+ @Test
+ public void required_mustRequestFromUpstreamForElementsThatHaveBeenRequestedLongAgo() throws Throwable {
+ optionalMultipleSubscribersTest(2, new Function<Long,TestSetup>() {
+ @Override
+ public TestSetup apply(Long subscribers) throws Throwable {
+ return new TestSetup(env, processorBufferSize) {{
+ ManualSubscriber<T> sub1 = newSubscriber();
+ sub1.request(20);
+
+ long totalRequests = expectRequest();
+ final T x = sendNextTFromUpstream();
+ expectNextElement(sub1, x);
+
+ if (totalRequests == 1) {
+ totalRequests += expectRequest();
+ }
+ final T y = sendNextTFromUpstream();
+ expectNextElement(sub1, y);
+
+ if (totalRequests == 2) {
+ totalRequests += expectRequest();
+ }
+
+ final ManualSubscriber<T> sub2 = newSubscriber();
+
+ // sub1 now has 18 pending
+ // sub2 has 0 pending
+
+ if (doesCoordinatedEmission()) {
+ sub2.expectNone(); // since sub2 hasn't requested anything yet
+
+ sub2.request(1);
+
+ final T z = sendNextTFromUpstream();
+ expectNextElement(sub1, z);
+ expectNextElement(sub2, z);
+ } else {
+ final T z = sendNextTFromUpstream();
+ expectNextElement(sub1, z,
+ "If the Processor coordinates requests/emissions when having multiple Subscribers"
+ + " at once, please override doesCoordinatedEmission() to return true in this "
+ + "IdentityProcessorVerification to allow this test to pass.");
+ sub2.expectNone(); // since sub2 hasn't requested anything yet
+
+ sub2.request(1);
+ expectNextElement(sub2, z);
+ }
+ if (totalRequests == 3) {
+ expectRequest();
+ }
+
+ // to avoid error messages during test harness shutdown
+ sendCompletion();
+ sub1.expectCompletion(env.defaultTimeoutMillis());
+ sub2.expectCompletion(env.defaultTimeoutMillis());
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }};
+ }
+ });
+ }
+
+ /////////////////////// TEST INFRASTRUCTURE //////////////////////
+
+ public void notVerified() {
+ publisherVerification.notVerified();
+ }
+
+ public void notVerified(String message) {
+ publisherVerification.notVerified(message);
+ }
+
+ /**
+ * Test for feature that REQUIRES multiple subscribers to be supported by Publisher.
+ */
+ public void optionalMultipleSubscribersTest(long requiredSubscribersSupport, Function<Long, TestSetup> body) throws Throwable {
+ if (requiredSubscribersSupport > maxSupportedSubscribers())
+ notVerified(String.format("The Publisher under test only supports %d subscribers, while this test requires at least %d to run.",
+ maxSupportedSubscribers(), requiredSubscribersSupport));
+ else body.apply(requiredSubscribersSupport);
+ }
+
+ public abstract class TestSetup extends ManualPublisher<T> {
+ final private ManualSubscriber<T> tees; // gives us access to an infinite stream of T values
+ private Set<T> seenTees = new HashSet<T>();
+
+ final Processor<T, T> processor;
+
+ public TestSetup(TestEnvironment env, int testBufferSize) throws InterruptedException {
+ super(env);
+ tees = env.newManualSubscriber(createHelperPublisher(Long.MAX_VALUE));
+ processor = createIdentityProcessor(testBufferSize);
+ subscribe(processor);
+ }
+
+ public ManualSubscriber<T> newSubscriber() throws InterruptedException {
+ return env.newManualSubscriber(processor);
+ }
+
+ public T nextT() throws InterruptedException {
+ final T t = tees.requestNextElement();
+ if (seenTees.contains(t)) {
+ env.flop(String.format("Helper publisher illegally produced the same element %s twice", t));
+ }
+ seenTees.add(t);
+ return t;
+ }
+
+ public void expectNextElement(ManualSubscriber<T> sub, T expected) throws InterruptedException {
+ final T elem = sub.nextElement(String.format("timeout while awaiting %s", expected));
+ if (!elem.equals(expected)) {
+ env.flop(String.format("Received `onNext(%s)` on downstream but expected `onNext(%s)`", elem, expected));
+ }
+ }
+
+ public void expectNextElement(ManualSubscriber<T> sub, T expected, String errorMessageAddendum) throws InterruptedException {
+ final T elem = sub.nextElement(String.format("timeout while awaiting %s. %s", expected, errorMessageAddendum));
+ if (!elem.equals(expected)) {
+ env.flop(String.format("Received `onNext(%s)` on downstream but expected `onNext(%s)`", elem, expected));
+ }
+ }
+
+ public T sendNextTFromUpstream() throws InterruptedException {
+ final T x = nextT();
+ sendNext(x);
+ return x;
+ }
+ }
+
+ public class ManualSubscriberWithErrorCollection<A> extends ManualSubscriberWithSubscriptionSupport<A> {
+ Promise<Throwable> error;
+
+ public ManualSubscriberWithErrorCollection(TestEnvironment env) {
+ super(env);
+ error = new Promise<Throwable>(env);
+ }
+
+ @Override
+ public void onError(Throwable cause) {
+ error.complete(cause);
+ }
+
+ public void expectError(Throwable cause) throws InterruptedException {
+ expectError(cause, env.defaultTimeoutMillis());
+ }
+
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void expectError(Throwable cause, long timeoutMillis) throws InterruptedException {
+ error.expectCompletion(timeoutMillis, "Did not receive expected error on downstream");
+ if (!cause.equals(error.value())) {
+ env.flop(String.format("Expected error %s but got %s", cause, error.value()));
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/PublisherVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,1245 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.tck.TestEnvironment.BlackholeSubscriberWithSubscriptionSupport;
+import org.reactivestreams.tck.TestEnvironment.Latch;
+import org.reactivestreams.tck.TestEnvironment.ManualSubscriber;
+import org.reactivestreams.tck.TestEnvironment.ManualSubscriberWithSubscriptionSupport;
+import org.reactivestreams.tck.flow.support.Function;
+import org.reactivestreams.tck.flow.support.Optional;
+import org.reactivestreams.tck.flow.support.PublisherVerificationRules;
+import org.testng.SkipException;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.lang.Override;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Provides tests for verifying {@code Publisher} specification rules.
+ *
+ * @see org.reactivestreams.Publisher
+ */
+public abstract class PublisherVerification<T> implements PublisherVerificationRules {
+
+ private static final String PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS_ENV = "PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS";
+ private static final long DEFAULT_PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS = 300L;
+
+ private final TestEnvironment env;
+
+ /**
+ * The amount of time after which a cancelled Subscriber reference should be dropped.
+ * See Rule 3.13 for details.
+ */
+ private final long publisherReferenceGCTimeoutMillis;
+
+ /**
+ * Constructs a new verification class using the given env and configuration.
+ *
+ * @param publisherReferenceGCTimeoutMillis used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher.
+ */
+ public PublisherVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis) {
+ this.env = env;
+ this.publisherReferenceGCTimeoutMillis = publisherReferenceGCTimeoutMillis;
+ }
+
+ /**
+ * Constructs a new verification class using the given env and configuration.
+ *
+ * The value for {@code publisherReferenceGCTimeoutMillis} will be obtained by using {@link PublisherVerification#envPublisherReferenceGCTimeoutMillis()}.
+ */
+ public PublisherVerification(TestEnvironment env) {
+ this.env = env;
+ this.publisherReferenceGCTimeoutMillis = envPublisherReferenceGCTimeoutMillis();
+ }
+
+ /**
+ * Tries to parse the env variable {@code PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS} as long and returns the value if present,
+ * OR its default value ({@link PublisherVerification#DEFAULT_PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS}).
+ *
+ * This value is used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher.
+ *
+ * @throws java.lang.IllegalArgumentException when unable to parse the env variable
+ */
+ public static long envPublisherReferenceGCTimeoutMillis() {
+ final String envMillis = System.getenv(PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS_ENV);
+ if (envMillis == null) return DEFAULT_PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS;
+ else try {
+ return Long.parseLong(envMillis);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS_ENV, envMillis), ex);
+ }
+ }
+
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a Publisher for a stream with exactly the given number of elements.
+ * If `elements` is `Long.MAX_VALUE` the produced stream must be infinite.
+ */
+ public abstract Publisher<T> createPublisher(long elements);
+
+ /**
+ * By implementing this method, additional TCK tests concerning a "failed" publishers will be run.
+ *
+ * The expected behaviour of the {@link Publisher} returned by this method is hand out a subscription,
+ * followed by signalling {@code onError} on it, as specified by Rule 1.9.
+ *
+ * If you ignore these additional tests, return {@code null} from this method.
+ */
+ public abstract Publisher<T> createFailedPublisher();
+
+
+ /**
+ * Override and return lower value if your Publisher is only able to produce a known number of elements.
+ * For example, if it is designed to return at-most-one element, return {@code 1} from this method.
+ *
+ * Defaults to {@code Long.MAX_VALUE - 1}, meaning that the Publisher can be produce a huge but NOT an unbounded number of elements.
+ *
+ * To mark your Publisher will *never* signal an {@code onComplete} override this method and return {@code Long.MAX_VALUE},
+ * which will result in *skipping all tests which require an onComplete to be triggered* (!).
+ */
+ public long maxElementsFromPublisher() {
+ return Long.MAX_VALUE - 1;
+ }
+
+ /**
+ * Override and return {@code true} in order to skip executing tests marked as {@code Stochastic}.
+ * Stochastic in this case means that the Rule is impossible or infeasible to deterministically verify—
+ * usually this means that this test case can yield false positives ("be green") even if for some case,
+ * the given implementation may violate the tested behaviour.
+ */
+ public boolean skipStochasticTests() {
+ return false;
+ }
+
+ /**
+ * In order to verify rule 3.3 of the reactive streams spec, this number will be used to check if a
+ * {@code Subscription} actually solves the "unbounded recursion" problem by not allowing the number of
+ * recursive calls to exceed the number returned by this method.
+ *
+ * @see <a href="https://github.com/reactive-streams/reactive-streams-jvm#3.3">reactive streams spec, rule 3.3</a>
+ * @see PublisherVerification#required_spec303_mustNotAllowUnboundedRecursion()
+ */
+ public long boundedDepthOfOnNextAndRequestRecursion() {
+ return 1;
+ }
+
+ ////////////////////// TEST ENV CLEANUP /////////////////////////////////////
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ env.clearAsyncErrors();
+ }
+
+ ////////////////////// TEST SETUP VERIFICATION //////////////////////////////
+
+ @Override @Test
+ public void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable {
+ activePublisherTest(1, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws InterruptedException {
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced no elements", pub));
+ sub.requestEndOfStream();
+ }
+
+ Optional<T> requestNextElementOrEndOfStream(Publisher<T> pub, ManualSubscriber<T> sub) throws InterruptedException {
+ return sub.requestNextElementOrEndOfStream(String.format("Timeout while waiting for next element from Publisher %s", pub));
+ }
+
+ });
+ }
+
+ @Override @Test
+ public void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable {
+ activePublisherTest(3, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws InterruptedException {
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced no elements", pub));
+ assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced only 1 element", pub));
+ assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced only 2 elements", pub));
+ sub.requestEndOfStream();
+ }
+
+ Optional<T> requestNextElementOrEndOfStream(Publisher<T> pub, ManualSubscriber<T> sub) throws InterruptedException {
+ return sub.requestNextElementOrEndOfStream(String.format("Timeout while waiting for next element from Publisher %s", pub));
+ }
+
+ });
+ }
+
+ @Override @Test
+ public void required_validate_maxElementsFromPublisher() throws Exception {
+ assertTrue(maxElementsFromPublisher() >= 0, "maxElementsFromPublisher MUST return a number >= 0");
+ }
+
+ @Override @Test
+ public void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception {
+ assertTrue(boundedDepthOfOnNextAndRequestRecursion() >= 1, "boundedDepthOfOnNextAndRequestRecursion must return a number >= 1");
+ }
+
+
+ ////////////////////// SPEC RULE VERIFICATION ///////////////////////////////
+
+ @Override @Test
+ public void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable {
+ activePublisherTest(5, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws InterruptedException {
+
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ try {
+ sub.expectNone(String.format("Publisher %s produced value before the first `request`: ", pub));
+ sub.request(1);
+ sub.nextElement(String.format("Publisher %s produced no element after first `request`", pub));
+ sub.expectNone(String.format("Publisher %s produced unrequested: ", pub));
+
+ sub.request(1);
+ sub.request(2);
+ sub.nextElements(3, env.defaultTimeoutMillis(), String.format("Publisher %s produced less than 3 elements after two respective `request` calls", pub));
+
+ sub.expectNone(String.format("Publisher %sproduced unrequested ", pub));
+ } finally {
+ sub.cancel();
+ }
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable {
+ final int elements = 3;
+ final int requested = 10;
+
+ activePublisherTest(elements, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.request(requested);
+ sub.nextElements(elements);
+ sub.expectCompletion();
+ }
+ });
+ }
+
+ @Override @Test
+ public void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable {
+ final int iterations = 100;
+ final int elements = 10;
+
+ stochasticTest(iterations, new Function<Integer, Void>() {
+ @Override
+ public Void apply(final Integer runNumber) throws Throwable {
+ activePublisherTest(elements, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final Latch completionLatch = new Latch(env);
+
+ final AtomicInteger gotElements = new AtomicInteger(0);
+ pub.subscribe(new Subscriber<T>() {
+ private Subscription subs;
+
+ private ConcurrentAccessBarrier concurrentAccessBarrier = new ConcurrentAccessBarrier();
+
+ /**
+ * Concept wise very similar to a {@link org.reactivestreams.tck.TestEnvironment.Latch}, serves to protect
+ * a critical section from concurrent access, with the added benefit of Thread tracking and same-thread-access awareness.
+ *
+ * Since a <i>Synchronous</i> Publisher may choose to synchronously (using the same {@link Thread}) call
+ * {@code onNext} directly from either {@code subscribe} or {@code request} a plain Latch is not enough
+ * to verify concurrent access safety - one needs to track if the caller is not still using the calling thread
+ * to enter subsequent critical sections ("nesting" them effectively).
+ */
+ final class ConcurrentAccessBarrier {
+ private AtomicReference<Thread> currentlySignallingThread = new AtomicReference<Thread>(null);
+ private volatile String previousSignal = null;
+
+ public void enterSignal(String signalName) {
+ if((!currentlySignallingThread.compareAndSet(null, Thread.currentThread())) && !isSynchronousSignal()) {
+ env.flop(String.format(
+ "Illegal concurrent access detected (entering critical section)! " +
+ "%s emited %s signal, before %s finished its %s signal.",
+ Thread.currentThread(), signalName, currentlySignallingThread.get(), previousSignal));
+ }
+ this.previousSignal = signalName;
+ }
+
+ public void leaveSignal(String signalName) {
+ currentlySignallingThread.set(null);
+ this.previousSignal = signalName;
+ }
+
+ private boolean isSynchronousSignal() {
+ return (previousSignal != null) && Thread.currentThread().equals(currentlySignallingThread.get());
+ }
+
+ }
+
+ @Override
+ public void onSubscribe(Subscription s) {
+ final String signal = "onSubscribe()";
+ concurrentAccessBarrier.enterSignal(signal);
+
+ subs = s;
+ subs.request(1);
+
+ concurrentAccessBarrier.leaveSignal(signal);
+ }
+
+ @Override
+ public void onNext(T ignore) {
+ final String signal = String.format("onNext(%s)", ignore);
+ concurrentAccessBarrier.enterSignal(signal);
+
+ if (gotElements.incrementAndGet() <= elements) // requesting one more than we know are in the stream (some Publishers need this)
+ subs.request(1);
+
+ concurrentAccessBarrier.leaveSignal(signal);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ final String signal = String.format("onError(%s)", t.getMessage());
+ concurrentAccessBarrier.enterSignal(signal);
+
+ // ignore value
+
+ concurrentAccessBarrier.leaveSignal(signal);
+ }
+
+ @Override
+ public void onComplete() {
+ final String signal = "onComplete()";
+ concurrentAccessBarrier.enterSignal(signal);
+
+ // entering for completeness
+
+ concurrentAccessBarrier.leaveSignal(signal);
+ completionLatch.close();
+ }
+ });
+
+ completionLatch.expectClose(
+ elements * env.defaultTimeoutMillis(),
+ String.format("Failed in iteration %d of %d. Expected completion signal after signalling %d elements (signalled %d), yet did not receive it",
+ runNumber, iterations, elements, gotElements.get()));
+ }
+ });
+ return null;
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable {
+ try {
+ whenHasErrorPublisherTest(new PublisherTestRun<T>() {
+ @Override
+ public void run(final Publisher<T> pub) throws InterruptedException {
+ final Latch onErrorlatch = new Latch(env);
+ final Latch onSubscribeLatch = new Latch(env);
+ pub.subscribe(new TestEnvironment.TestSubscriber<T>(env) {
+ @Override
+ public void onSubscribe(Subscription subs) {
+ onSubscribeLatch.assertOpen("Only one onSubscribe call expected");
+ onSubscribeLatch.close();
+ }
+ @Override
+ public void onError(Throwable cause) {
+ onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always");
+ onErrorlatch.assertOpen(String.format("Error-state Publisher %s called `onError` twice on new Subscriber", pub));
+ onErrorlatch.close();
+ }
+ });
+
+ onSubscribeLatch.expectClose("Should have received onSubscribe");
+ onErrorlatch.expectClose(String.format("Error-state Publisher %s did not call `onError` on new Subscriber", pub));
+
+ env.verifyNoAsyncErrors();
+ }
+ });
+ } catch (SkipException se) {
+ throw se;
+ } catch (Throwable ex) {
+ // we also want to catch AssertionErrors and anything the publisher may have thrown inside subscribe
+ // which was wrong of him - he should have signalled on error using onError
+ throw new RuntimeException(String.format("Publisher threw exception (%s) instead of signalling error via onError!", ex.getMessage()), ex);
+ }
+ }
+
+ @Override @Test
+ public void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable {
+ activePublisherTest(3, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.requestNextElement();
+ sub.requestNextElement();
+ sub.requestNextElement();
+ sub.requestEndOfStream();
+ sub.expectNone();
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable {
+ optionalActivePublisherTest(0, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.request(1);
+ sub.expectCompletion();
+ sub.expectNone();
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable {
+ notVerified(); // not really testable without more control over the Publisher
+ }
+
+ @Override @Test
+ public void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable {
+ activePublisherTest(1, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.request(10);
+ sub.nextElement();
+ sub.expectCompletion();
+
+ sub.request(10);
+ sub.expectNone();
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable {
+ notVerified(); // can we meaningfully test this, without more control over the publisher?
+ }
+
+ @Override @Test
+ public void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable {
+ notVerified(); // can we meaningfully test this?
+ }
+
+ @Override @Test
+ public void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable {
+ notVerified(); // can we meaningfully test this?
+ }
+
+ @Override @Test
+ public void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable {
+ activePublisherTest(0, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ try {
+ pub.subscribe(null);
+ env.flop("Publisher did not throw a NullPointerException when given a null Subscribe in subscribe");
+ } catch (NullPointerException ignored) {
+ // valid behaviour
+ }
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable {
+ activePublisherTest(0, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final Latch onSubscribeLatch = new Latch(env);
+ final AtomicReference<Subscription> cancel = new AtomicReference<Subscription>();
+ try {
+ pub.subscribe(new Subscriber<T>() {
+ @Override
+ public void onError(Throwable cause) {
+ onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always");
+ }
+
+ @Override
+ public void onSubscribe(Subscription subs) {
+ cancel.set(subs);
+ onSubscribeLatch.assertOpen("Only one onSubscribe call expected");
+ onSubscribeLatch.close();
+ }
+
+ @Override
+ public void onNext(T elem) {
+ onSubscribeLatch.assertClosed("onSubscribe should be called prior to onNext always");
+ }
+
+ @Override
+ public void onComplete() {
+ onSubscribeLatch.assertClosed("onSubscribe should be called prior to onComplete always");
+ }
+ });
+ onSubscribeLatch.expectClose("Should have received onSubscribe");
+ env.verifyNoAsyncErrorsNoDelay();
+ } finally {
+ Subscription s = cancel.getAndSet(null);
+ if (s != null) {
+ s.cancel();
+ }
+ }
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable {
+ whenHasErrorPublisherTest(new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final Latch onErrorLatch = new Latch(env);
+ final Latch onSubscribeLatch = new Latch(env);
+ ManualSubscriberWithSubscriptionSupport<T> sub = new ManualSubscriberWithSubscriptionSupport<T>(env) {
+ @Override
+ public void onError(Throwable cause) {
+ onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always");
+ onErrorLatch.assertOpen("Only one onError call expected");
+ onErrorLatch.close();
+ }
+
+ @Override
+ public void onSubscribe(Subscription subs) {
+ onSubscribeLatch.assertOpen("Only one onSubscribe call expected");
+ onSubscribeLatch.close();
+ }
+ };
+ pub.subscribe(sub);
+ onSubscribeLatch.expectClose("Should have received onSubscribe");
+ onErrorLatch.expectClose("Should have received onError");
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable {
+ notVerified(); // can we meaningfully test this?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#1.11
+ @Override @Test
+ public void optional_spec111_maySupportMultiSubscribe() throws Throwable {
+ optionalActivePublisherTest(1, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub1 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub2 = env.newManualSubscriber(pub);
+
+ try {
+ env.verifyNoAsyncErrors();
+ } finally {
+ try {
+ sub1.cancel();
+ } finally {
+ sub2.cancel();
+ }
+ }
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable {
+ optionalActivePublisherTest(1, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub1 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub2 = env.newManualSubscriber(pub);
+ // Since we're testing the case when the Publisher DOES support the optional multi-subscribers scenario,
+ // and decides if it handles them uni-cast or multi-cast, we don't know which subscriber will receive an
+ // onNext (and optional onComplete) signal(s) and which just onComplete signal.
+ // Plus, even if subscription assumed to be unicast, it's implementation choice, which one will be signalled
+ // with onNext.
+ sub1.requestNextElementOrEndOfStream();
+ sub2.requestNextElementOrEndOfStream();
+ try {
+ env.verifyNoAsyncErrors();
+ } finally {
+ try {
+ sub1.cancel();
+ } finally {
+ sub2.cancel();
+ }
+ }
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable {
+ optionalActivePublisherTest(5, true, new PublisherTestRun<T>() { // This test is skipped if the publisher is unbounded (never sends onComplete)
+ @Override
+ public void run(Publisher<T> pub) throws InterruptedException {
+ ManualSubscriber<T> sub1 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub2 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub3 = env.newManualSubscriber(pub);
+
+ sub1.request(1);
+ T x1 = sub1.nextElement(String.format("Publisher %s did not produce the requested 1 element on 1st subscriber", pub));
+ sub2.request(2);
+ List<T> y1 = sub2.nextElements(2, String.format("Publisher %s did not produce the requested 2 elements on 2nd subscriber", pub));
+ sub1.request(1);
+ T x2 = sub1.nextElement(String.format("Publisher %s did not produce the requested 1 element on 1st subscriber", pub));
+ sub3.request(3);
+ List<T> z1 = sub3.nextElements(3, String.format("Publisher %s did not produce the requested 3 elements on 3rd subscriber", pub));
+ sub3.request(1);
+ T z2 = sub3.nextElement(String.format("Publisher %s did not produce the requested 1 element on 3rd subscriber", pub));
+ sub3.request(1);
+ T z3 = sub3.nextElement(String.format("Publisher %s did not produce the requested 1 element on 3rd subscriber", pub));
+ sub3.requestEndOfStream(String.format("Publisher %s did not complete the stream as expected on 3rd subscriber", pub));
+ sub2.request(3);
+ List<T> y2 = sub2.nextElements(3, String.format("Publisher %s did not produce the requested 3 elements on 2nd subscriber", pub));
+ sub2.requestEndOfStream(String.format("Publisher %s did not complete the stream as expected on 2nd subscriber", pub));
+ sub1.request(2);
+ List<T> x3 = sub1.nextElements(2, String.format("Publisher %s did not produce the requested 2 elements on 1st subscriber", pub));
+ sub1.request(1);
+ T x4 = sub1.nextElement(String.format("Publisher %s did not produce the requested 1 element on 1st subscriber", pub));
+ sub1.requestEndOfStream(String.format("Publisher %s did not complete the stream as expected on 1st subscriber", pub));
+
+ @SuppressWarnings("unchecked")
+ List<T> r = new ArrayList<T>(Arrays.asList(x1, x2));
+ r.addAll(x3);
+ r.addAll(Collections.singleton(x4));
+
+ List<T> check1 = new ArrayList<T>(y1);
+ check1.addAll(y2);
+
+ //noinspection unchecked
+ List<T> check2 = new ArrayList<T>(z1);
+ check2.add(z2);
+ check2.add(z3);
+
+ assertEquals(r, check1, String.format("Publisher %s did not produce the same element sequence for subscribers 1 and 2", pub));
+ assertEquals(r, check2, String.format("Publisher %s did not produce the same element sequence for subscribers 1 and 3", pub));
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable {
+ optionalActivePublisherTest(3, false, new PublisherTestRun<T>() { // This test is skipped if the publisher cannot produce enough elements
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub1 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub2 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub3 = env.newManualSubscriber(pub);
+
+ List<T> received1 = new ArrayList<T>();
+ List<T> received2 = new ArrayList<T>();
+ List<T> received3 = new ArrayList<T>();
+
+ // if the publisher must touch it's source to notice it's been drained, the OnComplete won't come until we ask for more than it actually contains...
+ // edgy edge case?
+ sub1.request(4);
+ sub2.request(4);
+ sub3.request(4);
+
+ received1.addAll(sub1.nextElements(3));
+ received2.addAll(sub2.nextElements(3));
+ received3.addAll(sub3.nextElements(3));
+
+ // NOTE: can't check completion, the Publisher may not be able to signal it
+ // a similar test *with* completion checking is implemented
+
+ assertEquals(received1, received2, String.format("Expected elements to be signaled in the same sequence to 1st and 2nd subscribers"));
+ assertEquals(received2, received3, String.format("Expected elements to be signaled in the same sequence to 2nd and 3rd subscribers"));
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable {
+ optionalActivePublisherTest(3, true, new PublisherTestRun<T>() { // This test is skipped if the publisher is unbounded (never sends onComplete)
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub1 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub2 = env.newManualSubscriber(pub);
+ ManualSubscriber<T> sub3 = env.newManualSubscriber(pub);
+
+ List<T> received1 = new ArrayList<T>();
+ List<T> received2 = new ArrayList<T>();
+ List<T> received3 = new ArrayList<T>();
+
+ // if the publisher must touch it's source to notice it's been drained, the OnComplete won't come until we ask for more than it actually contains...
+ // edgy edge case?
+ sub1.request(4);
+ sub2.request(4);
+ sub3.request(4);
+
+ received1.addAll(sub1.nextElements(3));
+ received2.addAll(sub2.nextElements(3));
+ received3.addAll(sub3.nextElements(3));
+
+ sub1.expectCompletion();
+ sub2.expectCompletion();
+ sub3.expectCompletion();
+
+ assertEquals(received1, received2, String.format("Expected elements to be signaled in the same sequence to 1st and 2nd subscribers"));
+ assertEquals(received2, received3, String.format("Expected elements to be signaled in the same sequence to 2nd and 3rd subscribers"));
+ }
+ });
+ }
+
+ ///////////////////// SUBSCRIPTION TESTS //////////////////////////////////
+
+ @Override @Test
+ public void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable {
+ activePublisherTest(6, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub = new ManualSubscriber<T>(env) {
+ @Override
+ public void onSubscribe(Subscription subs) {
+ this.subscription.completeImmediatly(subs);
+
+ subs.request(1);
+ subs.request(1);
+ subs.request(1);
+ }
+
+ @Override
+ public void onNext(T element) {
+ Subscription subs = this.subscription.value();
+ subs.request(1);
+ }
+ };
+
+ env.subscribe(pub, sub);
+
+ env.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable {
+ final long oneMoreThanBoundedLimit = boundedDepthOfOnNextAndRequestRecursion() + 1;
+
+ activePublisherTest(oneMoreThanBoundedLimit, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final ThreadLocal<Long> stackDepthCounter = new ThreadLocal<Long>() {
+ @Override
+ protected Long initialValue() {
+ return 0L;
+ }
+ };
+
+ final Latch runCompleted = new Latch(env);
+
+ final ManualSubscriber<T> sub = new ManualSubscriberWithSubscriptionSupport<T>(env) {
+ // counts the number of signals received, used to break out from possibly infinite request/onNext loops
+ long signalsReceived = 0L;
+
+ @Override
+ public void onNext(T element) {
+ // NOT calling super.onNext as this test only cares about stack depths, not the actual values of elements
+ // which also simplifies this test as we do not have to drain the test buffer, which would otherwise be in danger of overflowing
+
+ signalsReceived += 1;
+ stackDepthCounter.set(stackDepthCounter.get() + 1);
+ if (env.debugEnabled()) {
+ env.debug(String.format("%s(recursion depth: %d)::onNext(%s)", this, stackDepthCounter.get(), element));
+ }
+
+ final long callsUntilNow = stackDepthCounter.get();
+ if (callsUntilNow > boundedDepthOfOnNextAndRequestRecursion()) {
+ env.flop(String.format("Got %d onNext calls within thread: %s, yet expected recursive bound was %d",
+ callsUntilNow, Thread.currentThread(), boundedDepthOfOnNextAndRequestRecursion()));
+
+ // stop the recursive call chain
+ runCompleted.close();
+ return;
+ } else if (signalsReceived >= oneMoreThanBoundedLimit) {
+ // since max number of signals reached, and recursion depth not exceeded, we judge this as a success and
+ // stop the recursive call chain
+ runCompleted.close();
+ return;
+ }
+
+ // request more right away, the Publisher must break the recursion
+ subscription.value().request(1);
+
+ stackDepthCounter.set(stackDepthCounter.get() - 1);
+ }
+
+ @Override
+ public void onComplete() {
+ super.onComplete();
+ runCompleted.close();
+ }
+
+ @Override
+ public void onError(Throwable cause) {
+ super.onError(cause);
+ runCompleted.close();
+ }
+ };
+
+ try {
+ env.subscribe(pub, sub);
+
+ sub.request(1); // kick-off the `request -> onNext -> request -> onNext -> ...`
+
+ final String msg = String.format("Unable to validate call stack depth safety, " +
+ "awaited at-most %s signals (`maxOnNextSignalsInRecursionTest()`) or completion",
+ oneMoreThanBoundedLimit);
+ runCompleted.expectClose(env.defaultTimeoutMillis(), msg);
+ env.verifyNoAsyncErrorsNoDelay();
+ } finally {
+ // since the request/onNext recursive calls may keep the publisher running "forever",
+ // we MUST cancel it manually before exiting this test case
+ sub.cancel();
+ }
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable {
+ activePublisherTest(3, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+
+ // override ManualSubscriberWithSubscriptionSupport#cancel because by default a ManualSubscriber will drop the
+ // subscription once it's cancelled (as expected).
+ // In this test however it must keep the cancelled Subscription and keep issuing `request(long)` to it.
+ ManualSubscriber<T> sub = new ManualSubscriberWithSubscriptionSupport<T>(env) {
+ @Override
+ public void cancel() {
+ if (subscription.isCompleted()) {
+ subscription.value().cancel();
+ } else {
+ env.flop("Cannot cancel a subscription before having received it");
+ }
+ }
+ };
+
+ env.subscribe(pub, sub);
+
+ sub.cancel();
+ sub.request(1);
+ sub.request(1);
+ sub.request(1);
+
+ sub.expectNone();
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable {
+ activePublisherTest(1, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+
+ // leak the Subscription
+ final Subscription subs = sub.subscription.value();
+
+ subs.cancel();
+ subs.cancel();
+ subs.cancel();
+
+ sub.expectNone();
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable {
+ activePublisherTest(10, false, new PublisherTestRun<T>() {
+ @Override public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.request(0);
+ sub.expectError(IllegalArgumentException.class);
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable {
+ activePublisherTest(10, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ final Random r = new Random();
+ sub.request(-r.nextInt(Integer.MAX_VALUE) - 1);
+ // we do require implementations to mention the rule number at the very least, or mentioning that the non-negative request is the problem
+ sub.expectError(IllegalArgumentException.class);
+ }
+ });
+ }
+
+ @Override @Test
+ public void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable {
+ optionalActivePublisherTest(10, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ final Random r = new Random();
+ sub.request(-r.nextInt(Integer.MAX_VALUE) - 1);
+ // we do require implementations to mention the rule number at the very least, or mentioning that the non-negative request is the problem
+ sub.expectErrorWithMessage(IllegalArgumentException.class, Arrays.asList("3.9", "non-positive subscription request", "negative subscription request"));
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable {
+ // the publisher is able to signal more elements than the subscriber will be requesting in total
+ final int publisherElements = 20;
+
+ final int demand1 = 10;
+ final int demand2 = 5;
+ final int totalDemand = demand1 + demand2;
+
+ activePublisherTest(publisherElements, false, new PublisherTestRun<T>() {
+ @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+
+ sub.request(demand1);
+ sub.request(demand2);
+
+ /*
+ NOTE: The order of the nextElement/cancel calls below is very important (!)
+
+ If this ordering was reversed, given an asynchronous publisher,
+ the following scenario would be *legal* and would break this test:
+
+ > AsyncPublisher receives request(10) - it does not emit data right away, it's asynchronous
+ > AsyncPublisher receives request(5) - demand is now 15
+ ! AsyncPublisher didn't emit any onNext yet (!)
+ > AsyncPublisher receives cancel() - handles it right away, by "stopping itself" for example
+ ! cancel was handled hefore the AsyncPublisher ever got the chance to emit data
+ ! the subscriber ends up never receiving even one element - the test is stuck (and fails, even on valid Publisher)
+
+ Which is why we must first expect an element, and then cancel, once the producing is "running".
+ */
+ sub.nextElement();
+ sub.cancel();
+
+ int onNextsSignalled = 1;
+
+ boolean stillBeingSignalled;
+ do {
+ // put asyncError if onNext signal received
+ sub.expectNone();
+ Throwable error = env.dropAsyncError();
+
+ if (error == null) {
+ stillBeingSignalled = false;
+ } else {
+ onNextsSignalled += 1;
+ stillBeingSignalled = true;
+ }
+
+ // if the Publisher tries to emit more elements than was requested (and/or ignores cancellation) this will throw
+ assertTrue(onNextsSignalled <= totalDemand,
+ String.format("Publisher signalled [%d] elements, which is more than the signalled demand: %d",
+ onNextsSignalled, totalDemand));
+
+ } while (stillBeingSignalled);
+ }
+ });
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+
+ @Override @Test
+ public void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable {
+ final ReferenceQueue<ManualSubscriber<T>> queue = new ReferenceQueue<ManualSubscriber<T>>();
+
+ final Function<Publisher<T>, WeakReference<ManualSubscriber<T>>> run = new Function<Publisher<T>, WeakReference<ManualSubscriber<T>>>() {
+ @Override
+ public WeakReference<ManualSubscriber<T>> apply(Publisher<T> pub) throws Exception {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ final WeakReference<ManualSubscriber<T>> ref = new WeakReference<ManualSubscriber<T>>(sub, queue);
+
+ sub.request(1);
+ sub.nextElement();
+ sub.cancel();
+
+ return ref;
+ }
+ };
+
+ activePublisherTest(3, false, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final WeakReference<ManualSubscriber<T>> ref = run.apply(pub);
+
+ // cancel may be run asynchronously so we add a sleep before running the GC
+ // to "resolve" the race
+ Thread.sleep(publisherReferenceGCTimeoutMillis);
+ System.gc();
+
+ if (!ref.equals(queue.remove(100))) {
+ env.flop(String.format("Publisher %s did not drop reference to test subscriber after subscription cancellation", pub));
+ }
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable {
+ final int totalElements = 3;
+
+ activePublisherTest(totalElements, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.request(Long.MAX_VALUE);
+
+ sub.nextElements(totalElements);
+ sub.expectCompletion();
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable {
+ final int totalElements = 3;
+
+ activePublisherTest(totalElements, true, new PublisherTestRun<T>() {
+ @Override
+ public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriber<T> sub = env.newManualSubscriber(pub);
+ sub.request(Long.MAX_VALUE / 2); // pending = Long.MAX_VALUE / 2
+ sub.request(Long.MAX_VALUE / 2); // pending = Long.MAX_VALUE - 1
+ sub.request(1); // pending = Long.MAX_VALUE
+
+ sub.nextElements(totalElements);
+ sub.expectCompletion();
+
+ try {
+ env.verifyNoAsyncErrorsNoDelay();
+ } finally {
+ sub.cancel();
+ }
+
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable {
+ activePublisherTest(Integer.MAX_VALUE, false, new PublisherTestRun<T>() {
+ @Override public void run(Publisher<T> pub) throws Throwable {
+ final ManualSubscriberWithSubscriptionSupport<T> sub = new BlackholeSubscriberWithSubscriptionSupport<T>(env) {
+ // arbitrarily set limit on nuber of request calls signalled, we expect overflow after already 2 calls,
+ // so 10 is relatively high and safe even if arbitrarily chosen
+ int callsCounter = 10;
+
+ @Override
+ public void onNext(T element) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("%s::onNext(%s)", this, element));
+ }
+ if (subscription.isCompleted()) {
+ if (callsCounter > 0) {
+ subscription.value().request(Long.MAX_VALUE - 1);
+ callsCounter--;
+ } else {
+ subscription.value().cancel();
+ }
+ } else {
+ env.flop(String.format("Subscriber::onNext(%s) called before Subscriber::onSubscribe", element));
+ }
+ }
+ };
+ env.subscribe(pub, sub, env.defaultTimeoutMillis());
+
+ // eventually triggers `onNext`, which will then trigger up to `callsCounter` times `request(Long.MAX_VALUE - 1)`
+ // we're pretty sure to overflow from those
+ sub.request(1);
+
+ // no onError should be signalled
+ try {
+ env.verifyNoAsyncErrors();
+ } finally {
+ sub.cancel();
+ }
+ }
+ });
+ }
+
+ ///////////////////// ADDITIONAL "COROLLARY" TESTS ////////////////////////
+
+ ///////////////////// TEST INFRASTRUCTURE /////////////////////////////////
+
+ public interface PublisherTestRun<T> {
+ public void run(Publisher<T> pub) throws Throwable;
+ }
+
+ /**
+ * Test for feature that SHOULD/MUST be implemented, using a live publisher.
+ *
+ * @param elements the number of elements the Publisher under test must be able to emit to run this test
+ * @param completionSignalRequired true if an {@code onComplete} signal is required by this test to run.
+ * If the tested Publisher is unable to signal completion, tests requireing onComplete signals will be skipped.
+ * To signal if your Publisher is able to signal completion see {@link PublisherVerification#maxElementsFromPublisher()}.
+ */
+ public void activePublisherTest(long elements, boolean completionSignalRequired, PublisherTestRun<T> body) throws Throwable {
+ if (elements > maxElementsFromPublisher()) {
+ throw new SkipException(String.format("Unable to run this test, as required elements nr: %d is higher than supported by given producer: %d", elements, maxElementsFromPublisher()));
+ } else if (completionSignalRequired && maxElementsFromPublisher() == Long.MAX_VALUE) {
+ throw new SkipException("Unable to run this test, as it requires an onComplete signal, " +
+ "which this Publisher is unable to provide (as signalled by returning Long.MAX_VALUE from `maxElementsFromPublisher()`)");
+ } else {
+ Publisher<T> pub = createPublisher(elements);
+ body.run(pub);
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ }
+
+ /**
+ * Test for feature that MAY be implemented. This test will be marked as SKIPPED if it fails.
+ *
+ * @param elements the number of elements the Publisher under test must be able to emit to run this test
+ * @param completionSignalRequired true if an {@code onComplete} signal is required by this test to run.
+ * If the tested Publisher is unable to signal completion, tests requireing onComplete signals will be skipped.
+ * To signal if your Publisher is able to signal completion see {@link PublisherVerification#maxElementsFromPublisher()}.
+ */
+ public void optionalActivePublisherTest(long elements, boolean completionSignalRequired, PublisherTestRun<T> body) throws Throwable {
+ if (elements > maxElementsFromPublisher()) {
+ throw new SkipException(String.format("Unable to run this test, as required elements nr: %d is higher than supported by given producer: %d", elements, maxElementsFromPublisher()));
+ } else if (completionSignalRequired && maxElementsFromPublisher() == Long.MAX_VALUE) {
+ throw new SkipException("Unable to run this test, as it requires an onComplete signal, " +
+ "which this Publisher is unable to provide (as signalled by returning Long.MAX_VALUE from `maxElementsFromPublisher()`)");
+ } else {
+
+ final Publisher<T> pub = createPublisher(elements);
+ final String skipMessage = "Skipped because tested publisher does NOT implement this OPTIONAL requirement.";
+
+ try {
+ potentiallyPendingTest(pub, body);
+ } catch (Exception ex) {
+ notVerified(skipMessage);
+ } catch (AssertionError ex) {
+ notVerified(skipMessage + " Reason for skipping was: " + ex.getMessage());
+ }
+ }
+ }
+
+ public static final String SKIPPING_NO_ERROR_PUBLISHER_AVAILABLE =
+ "Skipping because no error state Publisher provided, and the test requires it. " +
+ "Please implement PublisherVerification#createFailedPublisher to run this test.";
+
+ public static final String SKIPPING_OPTIONAL_TEST_FAILED =
+ "Skipping, because provided Publisher does not pass this *additional* verification.";
+ /**
+ * Additional test for Publisher in error state
+ */
+ public void whenHasErrorPublisherTest(PublisherTestRun<T> body) throws Throwable {
+ potentiallyPendingTest(createFailedPublisher(), body, SKIPPING_NO_ERROR_PUBLISHER_AVAILABLE);
+ }
+
+ public void potentiallyPendingTest(Publisher<T> pub, PublisherTestRun<T> body) throws Throwable {
+ potentiallyPendingTest(pub, body, SKIPPING_OPTIONAL_TEST_FAILED);
+ }
+
+ public void potentiallyPendingTest(Publisher<T> pub, PublisherTestRun<T> body, String message) throws Throwable {
+ if (pub != null) {
+ body.run(pub);
+ } else {
+ throw new SkipException(message);
+ }
+ }
+
+ /**
+ * Executes a given test body {@code n} times.
+ * All the test runs must pass in order for the stochastic test to pass.
+ */
+ public void stochasticTest(int n, Function<Integer, Void> body) throws Throwable {
+ if (skipStochasticTests()) {
+ notVerified("Skipping @Stochastic test because `skipStochasticTests()` returned `true`!");
+ }
+
+ for (int i = 0; i < n; i++) {
+ body.apply(i);
+ }
+ }
+
+ public void notVerified() {
+ throw new SkipException("Not verified by this TCK.");
+ }
+
+ /**
+ * Return this value from {@link PublisherVerification#maxElementsFromPublisher()} to mark that the given {@link org.reactivestreams.Publisher},
+ * is not able to signal completion. For example it is strictly a time-bound or unbounded source of data.
+ *
+ * <b>Returning this value from {@link PublisherVerification#maxElementsFromPublisher()} will result in skipping all TCK tests which require onComplete signals!</b>
+ */
+ public long publisherUnableToSignalOnComplete() {
+ return Long.MAX_VALUE;
+ }
+
+ public void notVerified(String message) {
+ throw new SkipException(message);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberBlackboxVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.tck.TestEnvironment.ManualPublisher;
+import org.reactivestreams.tck.TestEnvironment.ManualSubscriber;
+import org.reactivestreams.tck.flow.support.Optional;
+import org.reactivestreams.tck.flow.support.SubscriberBlackboxVerificationRules;
+import org.reactivestreams.tck.flow.support.TestException;
+import org.testng.SkipException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.reactivestreams.tck.SubscriberWhiteboxVerification.BlackboxSubscriberProxy;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Provides tests for verifying {@link org.reactivestreams.Subscriber} and {@link org.reactivestreams.Subscription}
+ * specification rules, without any modifications to the tested implementation (also known as "Black Box" testing).
+ *
+ * This verification is NOT able to check many of the rules of the spec, and if you want more
+ * verification of your implementation you'll have to implement {@code org.reactivestreams.tck.SubscriberWhiteboxVerification}
+ * instead.
+ *
+ * @see org.reactivestreams.Subscriber
+ * @see org.reactivestreams.Subscription
+ */
+public abstract class SubscriberBlackboxVerification<T> extends WithHelperPublisher<T>
+ implements SubscriberBlackboxVerificationRules {
+
+ protected final TestEnvironment env;
+
+ protected SubscriberBlackboxVerification(TestEnvironment env) {
+ this.env = env;
+ }
+
+ // USER API
+
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a new {@link org.reactivestreams.Subscriber} instance to be subjected to the testing logic.
+ */
+ public abstract Subscriber<T> createSubscriber();
+
+ /**
+ * Override this method if the Subscriber implementation you are verifying
+ * needs an external signal before it signals demand to its Publisher.
+ *
+ * By default this method does nothing.
+ */
+ public void triggerRequest(final Subscriber<? super T> subscriber) {
+ // this method is intentionally left blank
+ }
+
+ // ENV SETUP
+
+ /**
+ * Executor service used by the default provided asynchronous Publisher.
+ * @see #createHelperPublisher(long)
+ */
+ private ExecutorService publisherExecutor;
+ @BeforeClass public void startPublisherExecutorService() { publisherExecutor = Executors.newFixedThreadPool(4); }
+ @AfterClass public void shutdownPublisherExecutorService() { if (publisherExecutor != null) publisherExecutor.shutdown(); }
+ @Override public ExecutorService publisherExecutorService() { return publisherExecutor; }
+
+ ////////////////////// TEST ENV CLEANUP /////////////////////////////////////
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ env.clearAsyncErrors();
+ }
+
+ ////////////////////// SPEC RULE VERIFICATION ///////////////////////////////
+
+ @Override @Test
+ public void required_spec201_blackbox_mustSignalDemandViaSubscriptionRequest() throws Throwable {
+ blackboxSubscriberTest(new BlackboxTestStageTestRun() {
+ @Override
+ public void run(BlackboxTestStage stage) throws InterruptedException {
+ triggerRequest(stage.subProxy().sub());
+ final long requested = stage.expectRequest();// assuming subscriber wants to consume elements...
+ final long signalsToEmit = Math.min(requested, 512); // protecting against Subscriber which sends ridiculous large demand
+
+ // should cope with up to requested number of elements
+ for (int i = 0; i < signalsToEmit && sampleIsCancelled(stage, i, 10); i++)
+ stage.signalNext();
+
+ // we complete after `signalsToEmit` (which can be less than `requested`),
+ // which is legal under https://github.com/reactive-streams/reactive-streams-jvm#1.2
+ stage.sendCompletion();
+ }
+
+ /**
+ * In order to allow some "skid" and not check state on each iteration,
+ * only check {@code stage.isCancelled} every {@code checkInterval}'th iteration.
+ */
+ private boolean sampleIsCancelled(BlackboxTestStage stage, int i, int checkInterval) throws InterruptedException {
+ if (i % checkInterval == 0) return stage.isCancelled();
+ else return false;
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec202_blackbox_shouldAsynchronouslyDispatch() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable {
+ blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() {
+ @Override
+ public void run(BlackboxTestStage stage) throws Throwable {
+ final Subscription subs = new Subscription() {
+ @Override
+ public void request(long n) {
+ final Optional<StackTraceElement> onCompleteStackTraceElement = env.findCallerMethodInStackTrace("onComplete");
+ if (onCompleteStackTraceElement.isDefined()) {
+ final StackTraceElement stackElem = onCompleteStackTraceElement.get();
+ env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+
+ @Override
+ public void cancel() {
+ final Optional<StackTraceElement> onCompleteStackElement = env.findCallerMethodInStackTrace("onComplete");
+ if (onCompleteStackElement.isDefined()) {
+ final StackTraceElement stackElem = onCompleteStackElement.get();
+ env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+ };
+
+ final Subscriber<T> sub = createSubscriber();
+ sub.onSubscribe(subs);
+ sub.onComplete();
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable {
+ blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() {
+ @Override
+ public void run(BlackboxTestStage stage) throws Throwable {
+ final Subscription subs = new Subscription() {
+ @Override
+ public void request(long n) {
+ Throwable thr = new Throwable();
+ for (StackTraceElement stackElem : thr.getStackTrace()) {
+ if (stackElem.getMethodName().equals("onError")) {
+ env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+ }
+
+ @Override
+ public void cancel() {
+ Throwable thr = new Throwable();
+ for (StackTraceElement stackElem : thr.getStackTrace()) {
+ if (stackElem.getMethodName().equals("onError")) {
+ env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+ }
+ };
+
+ final Subscriber<T> sub = createSubscriber();
+ sub.onSubscribe(subs);
+ sub.onError(new TestException());
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec204_blackbox_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void required_spec205_blackbox_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Exception {
+ new BlackboxTestStage(env) {{
+ // try to subscribe another time, if the subscriber calls `probe.registerOnSubscribe` the test will fail
+ final TestEnvironment.Latch secondSubscriptionCancelled = new TestEnvironment.Latch(env);
+ sub().onSubscribe(
+ new Subscription() {
+ @Override
+ public void request(long elements) {
+ env.flop(String.format("Subscriber %s illegally called `subscription.request(%s)`!", sub(), elements));
+ }
+
+ @Override
+ public void cancel() {
+ secondSubscriptionCancelled.close();
+ }
+
+ @Override
+ public String toString() {
+ return "SecondSubscription(should get cancelled)";
+ }
+ });
+
+ secondSubscriptionCancelled.expectClose("Expected SecondSubscription given to subscriber to be cancelled, but `Subscription.cancel()` was not called.");
+ env.verifyNoAsyncErrorsNoDelay();
+ sendCompletion(); // we're done, complete the subscriber under test
+ }};
+ }
+
+ @Override @Test
+ public void untested_spec206_blackbox_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec207_blackbox_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ // the same thread part of the clause can be verified but that is not very useful, or is it?
+ }
+
+ @Override @Test
+ public void untested_spec208_blackbox_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable {
+ notVerified(); // cannot be meaningfully tested as black box, or can it?
+ }
+
+ @Override @Test
+ public void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable {
+ blackboxSubscriberTest(new BlackboxTestStageTestRun() {
+ @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void run(BlackboxTestStage stage) throws Throwable {
+ triggerRequest(stage.subProxy().sub());
+ final long notUsed = stage.expectRequest(); // received request signal
+ stage.sub().onComplete();
+ stage.subProxy().expectCompletion();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable {
+ blackboxSubscriberTest(new BlackboxTestStageTestRun() {
+ @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void run(BlackboxTestStage stage) throws Throwable {
+ final Subscriber<? super T> sub = stage.sub();
+ sub.onComplete();
+ stage.subProxy().expectCompletion();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable {
+ blackboxSubscriberTest(new BlackboxTestStageTestRun() {
+ @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void run(BlackboxTestStage stage) throws Throwable {
+ triggerRequest(stage.subProxy().sub());
+ final long notUsed = stage.expectRequest(); // received request signal
+ stage.sub().onError(new TestException()); // in response to that, we fail
+ stage.subProxy().expectError(Throwable.class);
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.10
+ @Override @Test
+ public void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable {
+ blackboxSubscriberTest(new BlackboxTestStageTestRun() {
+ @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void run(BlackboxTestStage stage) throws Throwable {
+
+ stage.sub().onError(new TestException());
+ stage.subProxy().expectError(Throwable.class);
+ }
+ });
+ }
+
+ @Override @Test
+ public void untested_spec211_blackbox_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec212_blackbox_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality() throws Throwable {
+ notVerified(); // cannot be meaningfully tested as black box, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec213_blackbox_failingOnSignalInvocation() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void required_spec213_blackbox_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() {
+ @Override
+ public void run(BlackboxTestStage stage) throws Throwable {
+
+ {
+ final Subscriber<T> sub = createSubscriber();
+ boolean gotNPE = false;
+ try {
+ sub.onSubscribe(null);
+ } catch(final NullPointerException expected) {
+ gotNPE = true;
+ }
+ assertTrue(gotNPE, "onSubscribe(null) did not throw NullPointerException");
+ }
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() {
+ @Override
+ public void run(BlackboxTestStage stage) throws Throwable {
+ final Subscription subscription = new Subscription() {
+ @Override public void request(final long elements) {}
+ @Override public void cancel() {}
+ };
+
+ {
+ final Subscriber<T> sub = createSubscriber();
+ boolean gotNPE = false;
+ sub.onSubscribe(subscription);
+ try {
+ sub.onNext(null);
+ } catch(final NullPointerException expected) {
+ gotNPE = true;
+ }
+ assertTrue(gotNPE, "onNext(null) did not throw NullPointerException");
+ }
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ @Override @Test
+ public void required_spec213_blackbox_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() {
+ @Override
+ public void run(BlackboxTestStage stage) throws Throwable {
+ final Subscription subscription = new Subscription() {
+ @Override public void request(final long elements) {}
+ @Override public void cancel() {}
+ };
+
+ {
+ final Subscriber<T> sub = createSubscriber();
+ boolean gotNPE = false;
+ sub.onSubscribe(subscription);
+ try {
+ sub.onError(null);
+ } catch(final NullPointerException expected) {
+ gotNPE = true;
+ }
+ assertTrue(gotNPE, "onError(null) did not throw NullPointerException");
+ }
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ ////////////////////// SUBSCRIPTION SPEC RULE VERIFICATION //////////////////
+
+ @Override @Test
+ public void untested_spec301_blackbox_mustNotBeCalledOutsideSubscriberContext() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec308_blackbox_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable {
+ notVerified(); // cannot be meaningfully tested as black box, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec310_blackbox_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec311_blackbox_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec314_blackbox_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec315_blackbox_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ @Override @Test
+ public void untested_spec316_blackbox_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ /////////////////////// ADDITIONAL "COROLLARY" TESTS ////////////////////////
+
+ /////////////////////// TEST INFRASTRUCTURE /////////////////////////////////
+
+ abstract class BlackboxTestStageTestRun {
+ public abstract void run(BlackboxTestStage stage) throws Throwable;
+ }
+
+ public void blackboxSubscriberTest(BlackboxTestStageTestRun body) throws Throwable {
+ BlackboxTestStage stage = new BlackboxTestStage(env, true);
+ body.run(stage);
+ }
+
+ public void blackboxSubscriberWithoutSetupTest(BlackboxTestStageTestRun body) throws Throwable {
+ BlackboxTestStage stage = new BlackboxTestStage(env, false);
+ body.run(stage);
+ }
+
+ public class BlackboxTestStage extends ManualPublisher<T> {
+ public Publisher<T> pub;
+ public ManualSubscriber<T> tees; // gives us access to an infinite stream of T values
+
+ public T lastT = null;
+ private Optional<BlackboxSubscriberProxy<T>> subProxy = Optional.empty();
+
+ public BlackboxTestStage(TestEnvironment env) throws InterruptedException {
+ this(env, true);
+ }
+
+ public BlackboxTestStage(TestEnvironment env, boolean runDefaultInit) throws InterruptedException {
+ super(env);
+ if (runDefaultInit) {
+ pub = this.createHelperPublisher(Long.MAX_VALUE);
+ tees = env.newManualSubscriber(pub);
+ Subscriber<T> sub = createSubscriber();
+ subProxy = Optional.of(createBlackboxSubscriberProxy(env, sub));
+ subscribe(subProxy.get());
+ }
+ }
+
+ public Subscriber<? super T> sub() {
+ return subscriber.value();
+ }
+
+ /**
+ * Proxy for the {@link #sub()} {@code Subscriber}, providing certain assertions on methods being called on the Subscriber.
+ */
+ public BlackboxSubscriberProxy<T> subProxy() {
+ return subProxy.get();
+ }
+
+ public Publisher<T> createHelperPublisher(long elements) {
+ return SubscriberBlackboxVerification.this.createHelperPublisher(elements);
+ }
+
+ public BlackboxSubscriberProxy<T> createBlackboxSubscriberProxy(TestEnvironment env, Subscriber<T> sub) {
+ return new BlackboxSubscriberProxy<T>(env, sub);
+ }
+
+ public T signalNext() throws InterruptedException {
+ T element = nextT();
+ sendNext(element);
+ return element;
+ }
+
+ public T nextT() throws InterruptedException {
+ lastT = tees.requestNextElement();
+ return lastT;
+ }
+
+ }
+
+ public void notVerified() {
+ throw new SkipException("Not verified using this TCK.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberWhiteboxVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,843 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.tck.TestEnvironment.*;
+import org.reactivestreams.tck.flow.support.Optional;
+import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules;
+import org.reactivestreams.tck.flow.support.TestException;
+import org.testng.SkipException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Provides whitebox style tests for verifying {@link org.reactivestreams.Subscriber}
+ * and {@link org.reactivestreams.Subscription} specification rules.
+ *
+ * @see org.reactivestreams.Subscriber
+ * @see org.reactivestreams.Subscription
+ */
+public abstract class SubscriberWhiteboxVerification<T> extends WithHelperPublisher<T>
+ implements SubscriberWhiteboxVerificationRules {
+
+ private final TestEnvironment env;
+
+ protected SubscriberWhiteboxVerification(TestEnvironment env) {
+ this.env = env;
+ }
+
+ // USER API
+
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a new {@link org.reactivestreams.Subscriber} instance to be subjected to the testing logic.
+ *
+ * In order to be meaningfully testable your Subscriber must inform the given
+ * `WhiteboxSubscriberProbe` of the respective events having been received.
+ */
+ public abstract Subscriber<T> createSubscriber(WhiteboxSubscriberProbe<T> probe);
+
+ // ENV SETUP
+
+ /**
+ * Executor service used by the default provided asynchronous Publisher.
+ * @see #createHelperPublisher(long)
+ */
+ private ExecutorService publisherExecutor;
+ @BeforeClass public void startPublisherExecutorService() { publisherExecutor = Executors.newFixedThreadPool(4); }
+ @AfterClass public void shutdownPublisherExecutorService() { if (publisherExecutor != null) publisherExecutor.shutdown(); }
+ @Override public ExecutorService publisherExecutorService() { return publisherExecutor; }
+
+ ////////////////////// TEST ENV CLEANUP /////////////////////////////////////
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ env.clearAsyncErrors();
+ }
+
+ ////////////////////// TEST SETUP VERIFICATION //////////////////////////////
+
+ @Test
+ public void required_exerciseWhiteboxHappyPath() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.puppet().triggerRequest(1);
+ stage.puppet().triggerRequest(1);
+
+ long receivedRequests = stage.expectRequest();
+
+ stage.signalNext();
+ stage.probe.expectNext(stage.lastT);
+
+ stage.puppet().triggerRequest(1);
+ if (receivedRequests == 1) {
+ stage.expectRequest();
+ }
+
+ stage.signalNext();
+ stage.probe.expectNext(stage.lastT);
+
+ stage.puppet().signalCancel();
+ stage.expectCancelling();
+
+ stage.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ ////////////////////// SPEC RULE VERIFICATION ///////////////////////////////
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.1
+ @Override @Test
+ public void required_spec201_mustSignalDemandViaSubscriptionRequest() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.puppet().triggerRequest(1);
+ stage.expectRequest();
+
+ stage.signalNext();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.2
+ @Override @Test
+ public void untested_spec202_shouldAsynchronouslyDispatch() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.3
+ @Override @Test
+ public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable {
+ subscriberTestWithoutSetup(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws Throwable {
+ final Subscription subs = new Subscription() {
+ @Override
+ public void request(long n) {
+ final Optional<StackTraceElement> onCompleteStackTraceElement = env.findCallerMethodInStackTrace("onComplete");
+ if (onCompleteStackTraceElement.isDefined()) {
+ final StackTraceElement stackElem = onCompleteStackTraceElement.get();
+ env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+
+ @Override
+ public void cancel() {
+ final Optional<StackTraceElement> onCompleteStackElement = env.findCallerMethodInStackTrace("onComplete");
+ if (onCompleteStackElement.isDefined()) {
+ final StackTraceElement stackElem = onCompleteStackElement.get();
+ env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+ };
+
+ stage.probe = stage.createWhiteboxSubscriberProbe(env);
+ final Subscriber<T> sub = createSubscriber(stage.probe);
+
+ sub.onSubscribe(subs);
+ sub.onComplete();
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.3
+ @Override @Test
+ public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable {
+ subscriberTestWithoutSetup(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws Throwable {
+ final Subscription subs = new Subscription() {
+ @Override
+ public void request(long n) {
+ Throwable thr = new Throwable();
+ for (StackTraceElement stackElem : thr.getStackTrace()) {
+ if (stackElem.getMethodName().equals("onError")) {
+ env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+ }
+
+ @Override
+ public void cancel() {
+ Throwable thr = new Throwable();
+ for (StackTraceElement stackElem : thr.getStackTrace()) {
+ if (stackElem.getMethodName().equals("onError")) {
+ env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)",
+ stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber()));
+ }
+ }
+ }
+ };
+
+ stage.probe = stage.createWhiteboxSubscriberProbe(env);
+ final Subscriber<T> sub = createSubscriber(stage.probe);
+
+ sub.onSubscribe(subs);
+ sub.onError(new TestException());
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.4
+ @Override @Test
+ public void untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.5
+ @Override @Test
+ public void required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws Throwable {
+ // try to subscribe another time, if the subscriber calls `probe.registerOnSubscribe` the test will fail
+ final Latch secondSubscriptionCancelled = new Latch(env);
+ final Subscriber<? super T> sub = stage.sub();
+ final Subscription subscription = new Subscription() {
+ @Override
+ public void request(long elements) {
+ // ignore...
+ }
+
+ @Override
+ public void cancel() {
+ secondSubscriptionCancelled.close();
+ }
+
+ @Override
+ public String toString() {
+ return "SecondSubscription(should get cancelled)";
+ }
+ };
+ sub.onSubscribe(subscription);
+
+ secondSubscriptionCancelled.expectClose("Expected 2nd Subscription given to subscriber to be cancelled, but `Subscription.cancel()` was not called");
+ env.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.6
+ @Override @Test
+ public void untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.7
+ @Override @Test
+ public void untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ // the same thread part of the clause can be verified but that is not very useful, or is it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.8
+ @Override @Test
+ public void required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.puppet().triggerRequest(1);
+ stage.puppet().signalCancel();
+ stage.expectRequest();
+ stage.signalNext();
+
+ stage.puppet().triggerRequest(1);
+ stage.puppet().triggerRequest(1);
+
+ stage.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.9
+ @Override @Test
+ public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.puppet().triggerRequest(1);
+ stage.sendCompletion();
+ stage.probe.expectCompletion();
+
+ stage.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.9
+ @Override @Test
+ public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.sendCompletion();
+ stage.probe.expectCompletion();
+
+ stage.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.10
+ @Override @Test
+ public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.puppet().triggerRequest(1);
+ stage.puppet().triggerRequest(1);
+
+ Exception ex = new TestException();
+ stage.sendError(ex);
+ stage.probe.expectError(ex);
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.10
+ @Override @Test
+ public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ Exception ex = new TestException();
+ stage.sendError(ex);
+ stage.probe.expectError(ex);
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.11
+ @Override @Test
+ public void untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.12
+ @Override @Test
+ public void untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation() throws Throwable {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13
+ @Override @Test
+ public void untested_spec213_failingOnSignalInvocation() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13
+ @Override @Test
+ public void required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws Throwable {
+
+ final Subscriber<? super T> sub = stage.sub();
+ boolean gotNPE = false;
+ try {
+ sub.onSubscribe(null);
+ } catch (final NullPointerException expected) {
+ gotNPE = true;
+ }
+
+ assertTrue(gotNPE, "onSubscribe(null) did not throw NullPointerException");
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13
+ @Override @Test
+ public void required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws Throwable {
+
+ final Subscriber<? super T> sub = stage.sub();
+ boolean gotNPE = false;
+ try {
+ sub.onNext(null);
+ } catch (final NullPointerException expected) {
+ gotNPE = true;
+ }
+
+ assertTrue(gotNPE, "onNext(null) did not throw NullPointerException");
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13
+ @Override @Test
+ public void required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws Throwable {
+
+ final Subscriber<? super T> sub = stage.sub();
+ boolean gotNPE = false;
+ try {
+ sub.onError(null);
+ } catch (final NullPointerException expected) {
+ gotNPE = true;
+ } finally {
+ assertTrue(gotNPE, "onError(null) did not throw NullPointerException");
+ }
+
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ });
+ }
+
+
+ ////////////////////// SUBSCRIPTION SPEC RULE VERIFICATION //////////////////
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.1
+ @Override @Test
+ public void untested_spec301_mustNotBeCalledOutsideSubscriberContext() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.8
+ @Override @Test
+ public void required_spec308_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable {
+ subscriberTest(new TestStageTestRun() {
+ @Override
+ public void run(WhiteboxTestStage stage) throws InterruptedException {
+ stage.puppet().triggerRequest(2);
+ long requestedElements = stage.expectRequest();
+ stage.probe.expectNext(stage.signalNext());
+ // Some subscribers may only request one element at a time.
+ if (requestedElements < 2) {
+ stage.expectRequest();
+ }
+ stage.probe.expectNext(stage.signalNext());
+
+ stage.probe.expectNone();
+ stage.puppet().triggerRequest(3);
+
+ stage.verifyNoAsyncErrors();
+ }
+ });
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.10
+ @Override @Test
+ public void untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.11
+ @Override @Test
+ public void untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.14
+ @Override @Test
+ public void untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.15
+ @Override @Test
+ public void untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.16
+ @Override @Test
+ public void untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception {
+ notVerified(); // cannot be meaningfully tested, or can it?
+ }
+
+ /////////////////////// ADDITIONAL "COROLLARY" TESTS ////////////////////////
+
+ /////////////////////// TEST INFRASTRUCTURE /////////////////////////////////
+
+ abstract class TestStageTestRun {
+ public abstract void run(WhiteboxTestStage stage) throws Throwable;
+ }
+
+ /**
+ * Prepares subscriber and publisher pair (by subscribing the first to the latter),
+ * and then hands over the tests {@link WhiteboxTestStage} over to the test.
+ *
+ * The test stage is, like in a puppet show, used to orchestrate what each participant should do.
+ * Since this is a whitebox test, this allows the stage to completely control when and how to signal / expect signals.
+ */
+ public void subscriberTest(TestStageTestRun body) throws Throwable {
+ WhiteboxTestStage stage = new WhiteboxTestStage(env, true);
+ body.run(stage);
+ }
+
+ /**
+ * Provides a {@link WhiteboxTestStage} without performing any additional setup,
+ * like the {@link #subscriberTest(SubscriberWhiteboxVerification.TestStageTestRun)} would.
+ *
+ * Use this method to write tests in which you need full control over when and how the initial {@code subscribe} is signalled.
+ */
+ public void subscriberTestWithoutSetup(TestStageTestRun body) throws Throwable {
+ WhiteboxTestStage stage = new WhiteboxTestStage(env, false);
+ body.run(stage);
+ }
+
+ /**
+ * Test for feature that MAY be implemented. This test will be marked as SKIPPED if it fails.
+ */
+ public void optionalSubscriberTestWithoutSetup(TestStageTestRun body) throws Throwable {
+ try {
+ subscriberTestWithoutSetup(body);
+ } catch (Exception ex) {
+ notVerified("Skipped because tested publisher does NOT implement this OPTIONAL requirement.");
+ }
+ }
+
+ public class WhiteboxTestStage extends ManualPublisher<T> {
+ public Publisher<T> pub;
+ public ManualSubscriber<T> tees; // gives us access to a stream T values
+ public WhiteboxSubscriberProbe<T> probe;
+
+ public T lastT = null;
+
+ public WhiteboxTestStage(TestEnvironment env) throws InterruptedException {
+ this(env, true);
+ }
+
+ public WhiteboxTestStage(TestEnvironment env, boolean runDefaultInit) throws InterruptedException {
+ super(env);
+ if (runDefaultInit) {
+ pub = this.createHelperPublisher(Long.MAX_VALUE);
+ tees = env.newManualSubscriber(pub);
+ probe = new WhiteboxSubscriberProbe<T>(env, subscriber);
+ subscribe(createSubscriber(probe));
+ probe.puppet.expectCompletion(env.defaultTimeoutMillis(), String.format("Subscriber %s did not `registerOnSubscribe`", sub()));
+ env.verifyNoAsyncErrorsNoDelay();
+ }
+ }
+
+ public Subscriber<? super T> sub() {
+ return subscriber.value();
+ }
+
+ public SubscriberPuppet puppet() {
+ return probe.puppet();
+ }
+
+ public WhiteboxSubscriberProbe<T> probe() {
+ return probe;
+ }
+
+ public Publisher<T> createHelperPublisher(long elements) {
+ return SubscriberWhiteboxVerification.this.createHelperPublisher(elements);
+ }
+
+ public WhiteboxSubscriberProbe<T> createWhiteboxSubscriberProbe(TestEnvironment env) {
+ return new WhiteboxSubscriberProbe<T>(env, subscriber);
+ }
+
+ public T signalNext() throws InterruptedException {
+ return signalNext(nextT());
+ }
+
+ private T signalNext(T element) throws InterruptedException {
+ sendNext(element);
+ return element;
+ }
+
+ public T nextT() throws InterruptedException {
+ lastT = tees.requestNextElement();
+ return lastT;
+ }
+
+ public void verifyNoAsyncErrors() {
+ env.verifyNoAsyncErrors();
+ }
+ }
+
+ /**
+ * This class is intented to be used as {@code Subscriber} decorator and should be used in {@code pub.subscriber(...)} calls,
+ * in order to allow intercepting calls on the underlying {@code Subscriber}.
+ * This delegation allows the proxy to implement {@link BlackboxProbe} assertions.
+ */
+ public static class BlackboxSubscriberProxy<T> extends BlackboxProbe<T> implements Subscriber<T> {
+
+ public BlackboxSubscriberProxy(TestEnvironment env, Subscriber<T> subscriber) {
+ super(env, Promise.<Subscriber<? super T>>completed(env, subscriber));
+ }
+
+ @Override
+ public void onSubscribe(Subscription s) {
+ sub().onSubscribe(s);
+ }
+
+ @Override
+ public void onNext(T t) {
+ registerOnNext(t);
+ sub().onNext(t);
+ }
+
+ @Override
+ public void onError(Throwable cause) {
+ registerOnError(cause);
+ sub().onError(cause);
+ }
+
+ @Override
+ public void onComplete() {
+ registerOnComplete();
+ sub().onComplete();
+ }
+ }
+
+ public static class BlackboxProbe<T> implements SubscriberProbe<T> {
+ protected final TestEnvironment env;
+ protected final Promise<Subscriber<? super T>> subscriber;
+
+ protected final Receptacle<T> elements;
+ protected final Promise<Throwable> error;
+
+ public BlackboxProbe(TestEnvironment env, Promise<Subscriber<? super T>> subscriber) {
+ this.env = env;
+ this.subscriber = subscriber;
+ elements = new Receptacle<T>(env);
+ error = new Promise<Throwable>(env);
+ }
+
+ @Override
+ public void registerOnNext(T element) {
+ elements.add(element);
+ }
+
+ @Override
+ public void registerOnComplete() {
+ try {
+ elements.complete();
+ } catch (IllegalStateException ex) {
+ // "Queue full", onComplete was already called
+ env.flop("subscriber::onComplete was called a second time, which is illegal according to Rule 1.7");
+ }
+ }
+
+ @Override
+ public void registerOnError(Throwable cause) {
+ try {
+ error.complete(cause);
+ } catch (IllegalStateException ex) {
+ // "Queue full", onError was already called
+ env.flop("subscriber::onError was called a second time, which is illegal according to Rule 1.7");
+ }
+ }
+
+ public T expectNext() throws InterruptedException {
+ return elements.next(env.defaultTimeoutMillis(), String.format("Subscriber %s did not call `registerOnNext(_)`", sub()));
+ }
+
+ public void expectNext(T expected) throws InterruptedException {
+ expectNext(expected, env.defaultTimeoutMillis());
+ }
+
+ public void expectNext(T expected, long timeoutMillis) throws InterruptedException {
+ T received = elements.next(timeoutMillis, String.format("Subscriber %s did not call `registerOnNext(%s)`", sub(), expected));
+ if (!received.equals(expected)) {
+ env.flop(String.format("Subscriber %s called `registerOnNext(%s)` rather than `registerOnNext(%s)`", sub(), received, expected));
+ }
+ }
+
+ public Subscriber<? super T> sub() {
+ return subscriber.value();
+ }
+
+ public void expectCompletion() throws InterruptedException {
+ expectCompletion(env.defaultTimeoutMillis());
+ }
+
+ public void expectCompletion(long timeoutMillis) throws InterruptedException {
+ expectCompletion(timeoutMillis, String.format("Subscriber %s did not call `registerOnComplete()`", sub()));
+ }
+
+ public void expectCompletion(long timeoutMillis, String msg) throws InterruptedException {
+ elements.expectCompletion(timeoutMillis, msg);
+ }
+
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public <E extends Throwable> void expectErrorWithMessage(Class<E> expected, String requiredMessagePart) throws InterruptedException {
+ final E err = expectError(expected);
+ String message = err.getMessage();
+ assertTrue(message.contains(requiredMessagePart),
+ String.format("Got expected exception %s but missing message [%s], was: %s", err.getClass(), requiredMessagePart, expected));
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected) throws InterruptedException {
+ return expectError(expected, env.defaultTimeoutMillis());
+ }
+
+ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"})
+ public <E extends Throwable> E expectError(Class<E> expected, long timeoutMillis) throws InterruptedException {
+ error.expectCompletion(timeoutMillis, String.format("Subscriber %s did not call `registerOnError(%s)`", sub(), expected));
+ if (error.value() == null) {
+ return env.flopAndFail(String.format("Subscriber %s did not call `registerOnError(%s)`", sub(), expected));
+ } else if (expected.isInstance(error.value())) {
+ return (E) error.value();
+ } else {
+ return env.flopAndFail(String.format("Subscriber %s called `registerOnError(%s)` rather than `registerOnError(%s)`", sub(), error.value(), expected));
+ }
+ }
+
+ public void expectError(Throwable expected) throws InterruptedException {
+ expectError(expected, env.defaultTimeoutMillis());
+ }
+
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void expectError(Throwable expected, long timeoutMillis) throws InterruptedException {
+ error.expectCompletion(timeoutMillis, String.format("Subscriber %s did not call `registerOnError(%s)`", sub(), expected));
+ if (error.value() != expected) {
+ env.flop(String.format("Subscriber %s called `registerOnError(%s)` rather than `registerOnError(%s)`", sub(), error.value(), expected));
+ }
+ }
+
+ public void expectNone() throws InterruptedException {
+ expectNone(env.defaultNoSignalsTimeoutMillis());
+ }
+
+ public void expectNone(long withinMillis) throws InterruptedException {
+ elements.expectNone(withinMillis, "Expected nothing");
+ }
+
+ }
+
+ public static class WhiteboxSubscriberProbe<T> extends BlackboxProbe<T> implements SubscriberPuppeteer {
+ protected Promise<SubscriberPuppet> puppet;
+
+ public WhiteboxSubscriberProbe(TestEnvironment env, Promise<Subscriber<? super T>> subscriber) {
+ super(env, subscriber);
+ puppet = new Promise<SubscriberPuppet>(env);
+ }
+
+ private SubscriberPuppet puppet() {
+ return puppet.value();
+ }
+
+ @Override
+ public void registerOnSubscribe(SubscriberPuppet p) {
+ if (!puppet.isCompleted()) {
+ puppet.complete(p);
+ }
+ }
+
+ }
+
+ public interface SubscriberPuppeteer {
+
+ /**
+ * Must be called by the test subscriber when it has successfully registered a subscription
+ * inside the `onSubscribe` method.
+ */
+ void registerOnSubscribe(SubscriberPuppet puppet);
+ }
+
+ public interface SubscriberProbe<T> {
+
+ /**
+ * Must be called by the test subscriber when it has received an`onNext` event.
+ */
+ void registerOnNext(T element);
+
+ /**
+ * Must be called by the test subscriber when it has received an `onComplete` event.
+ */
+ void registerOnComplete();
+
+ /**
+ * Must be called by the test subscriber when it has received an `onError` event.
+ */
+ void registerOnError(Throwable cause);
+
+ }
+
+ /**
+ * Implement this puppet in your Whitebox style tests.
+ * The test suite will invoke the specific trigger/signal methods requesting you to execute the specific action.
+ * Since this is a whitebox style test, you're allowed and expected to use knowladge about your implementation to
+ * make implement these calls.
+ */
+ public interface SubscriberPuppet {
+
+ /**
+ * Ensure that at least {@code elements} are eventually requested by your {@link Subscriber}, if it hasn't already
+ * requested that many elements.
+ * <p>
+ * This does not necessarily have to correlate 1:1 with a {@code Subscription.request(elements)} call, but the sum
+ * of the elements requested by your {@code Subscriber} must eventually be at least the the sum of the elements
+ * triggered to be requested by all the invocations of this method.
+ * <p>
+ * Additionally, subscribers are permitted to delay requesting elements until previous requests for elements have
+ * been fulfilled. For example, a subscriber that only requests one element at a time may fulfill the request made
+ * by this method by requesting one element {@code elements} times, waiting for each element to arrive before the
+ * next request is made.
+ * <p>
+ * Before sending any element to the subscriber, the TCK must wait for the subscriber to request that element, and
+ * must be prepared for the subscriber to only request one element at a time, it is not enough for the TCK to
+ * simply invoke this method before sending elements.
+ */
+ void triggerRequest(long elements);
+
+ /**
+ * Trigger {@code cancel()} on your {@link Subscriber}
+ */
+ void signalCancel();
+ }
+
+ public void notVerified() {
+ throw new SkipException("Not verified using this TCK.");
+ }
+
+ public void notVerified(String msg) {
+ throw new SkipException(msg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/TestEnvironment.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,1168 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.tck.flow.support.Optional;
+import org.reactivestreams.tck.flow.support.SubscriberBufferOverflowException;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+public class TestEnvironment {
+ public static final int TEST_BUFFER_SIZE = 16;
+
+ private static final String DEFAULT_TIMEOUT_MILLIS_ENV = "DEFAULT_TIMEOUT_MILLIS";
+ private static final long DEFAULT_TIMEOUT_MILLIS = 100;
+
+ private static final String DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS_ENV = "DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS";
+ private static final String DEFAULT_POLL_TIMEOUT_MILLIS_ENV = "DEFAULT_POLL_TIMEOUT_MILLIS_ENV";
+
+ private final long defaultTimeoutMillis;
+ private final long defaultPollTimeoutMillis;
+ private final long defaultNoSignalsTimeoutMillis;
+ private final boolean printlnDebug;
+
+ private CopyOnWriteArrayList<Throwable> asyncErrors = new CopyOnWriteArrayList<Throwable>();
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ * @param defaultTimeoutMillis default timeout to be used in all expect* methods
+ * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore
+ * @param defaultPollTimeoutMillis default amount of time to poll for events if {@code defaultTimeoutMillis} isn't
+ * preempted by an asynchronous event.
+ * @param printlnDebug if true, signals such as OnNext / Request / OnComplete etc will be printed to standard output,
+ */
+ public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis, long defaultPollTimeoutMillis,
+ boolean printlnDebug) {
+ this.defaultTimeoutMillis = defaultTimeoutMillis;
+ this.defaultPollTimeoutMillis = defaultPollTimeoutMillis;
+ this.defaultNoSignalsTimeoutMillis = defaultNoSignalsTimeoutMillis;
+ this.printlnDebug = printlnDebug;
+ }
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ * @param defaultTimeoutMillis default timeout to be used in all expect* methods
+ * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore
+ * @param printlnDebug if true, signals such as OnNext / Request / OnComplete etc will be printed to standard output,
+ */
+ public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis, boolean printlnDebug) {
+ this(defaultTimeoutMillis, defaultNoSignalsTimeoutMillis, defaultTimeoutMillis, printlnDebug);
+ }
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ *
+ * @param defaultTimeoutMillis default timeout to be used in all expect* methods
+ * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore
+ * @param defaultPollTimeoutMillis default amount of time to poll for events if {@code defaultTimeoutMillis} isn't
+ * preempted by an asynchronous event.
+ */
+ public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis, long defaultPollTimeoutMillis) {
+ this(defaultTimeoutMillis, defaultNoSignalsTimeoutMillis, defaultPollTimeoutMillis, false);
+ }
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ *
+ * @param defaultTimeoutMillis default timeout to be used in all expect* methods
+ * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore
+ */
+ public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis) {
+ this(defaultTimeoutMillis, defaultTimeoutMillis, defaultNoSignalsTimeoutMillis);
+ }
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ *
+ * @param defaultTimeoutMillis default timeout to be used in all expect* methods
+ */
+ public TestEnvironment(long defaultTimeoutMillis) {
+ this(defaultTimeoutMillis, defaultTimeoutMillis, defaultTimeoutMillis);
+ }
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ *
+ * The default timeout for all expect* methods will be obtained by either the env variable {@code DEFAULT_TIMEOUT_MILLIS}
+ * or the default value ({@link TestEnvironment#DEFAULT_TIMEOUT_MILLIS}) will be used.
+ *
+ * @param printlnDebug if true, signals such as OnNext / Request / OnComplete etc will be printed to standard output,
+ * often helpful to pinpoint simple race conditions etc.
+ */
+ public TestEnvironment(boolean printlnDebug) {
+ this(envDefaultTimeoutMillis(), envDefaultNoSignalsTimeoutMillis(), envDefaultPollTimeoutMillis(), printlnDebug);
+ }
+
+ /**
+ * Tests must specify the timeout for expected outcome of asynchronous
+ * interactions. Longer timeout does not invalidate the correctness of
+ * the implementation, but can in some cases result in longer time to
+ * run the tests.
+ *
+ * The default timeout for all expect* methods will be obtained by either the env variable {@code DEFAULT_TIMEOUT_MILLIS}
+ * or the default value ({@link TestEnvironment#DEFAULT_TIMEOUT_MILLIS}) will be used.
+ */
+ public TestEnvironment() {
+ this(envDefaultTimeoutMillis(), envDefaultNoSignalsTimeoutMillis());
+ }
+
+ /** This timeout is used when waiting for a signal to arrive. */
+ public long defaultTimeoutMillis() {
+ return defaultTimeoutMillis;
+ }
+
+ /**
+ * This timeout is used when asserting that no further signals are emitted.
+ * Note that this timeout default
+ */
+ public long defaultNoSignalsTimeoutMillis() {
+ return defaultNoSignalsTimeoutMillis;
+ }
+
+ /**
+ * The default amount of time to poll for events if {@code defaultTimeoutMillis} isn't preempted by an asynchronous
+ * event.
+ */
+ public long defaultPollTimeoutMillis() {
+ return defaultPollTimeoutMillis;
+ }
+
+ /**
+ * Tries to parse the env variable {@code DEFAULT_TIMEOUT_MILLIS} as long and returns the value if present OR its default value.
+ *
+ * @throws java.lang.IllegalArgumentException when unable to parse the env variable
+ */
+ public static long envDefaultTimeoutMillis() {
+ final String envMillis = System.getenv(DEFAULT_TIMEOUT_MILLIS_ENV);
+ if (envMillis == null) return DEFAULT_TIMEOUT_MILLIS;
+ else try {
+ return Long.parseLong(envMillis);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", DEFAULT_TIMEOUT_MILLIS_ENV, envMillis), ex);
+ }
+ }
+
+ /**
+ * Tries to parse the env variable {@code DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS} as long and returns the value if present OR its default value.
+ *
+ * @throws java.lang.IllegalArgumentException when unable to parse the env variable
+ */
+ public static long envDefaultNoSignalsTimeoutMillis() {
+ final String envMillis = System.getenv(DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS_ENV);
+ if (envMillis == null) return envDefaultTimeoutMillis();
+ else try {
+ return Long.parseLong(envMillis);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS_ENV, envMillis), ex);
+ }
+ }
+
+ /**
+ * Tries to parse the env variable {@code DEFAULT_POLL_TIMEOUT_MILLIS_ENV} as long and returns the value if present OR its default value.
+ *
+ * @throws java.lang.IllegalArgumentException when unable to parse the env variable
+ */
+ public static long envDefaultPollTimeoutMillis() {
+ final String envMillis = System.getenv(DEFAULT_POLL_TIMEOUT_MILLIS_ENV);
+ if (envMillis == null) return envDefaultTimeoutMillis();
+ else try {
+ return Long.parseLong(envMillis);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", DEFAULT_POLL_TIMEOUT_MILLIS_ENV, envMillis), ex);
+ }
+ }
+
+ /**
+ * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously.
+ * This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required.
+ *
+ * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution.
+ * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly
+ * from the environment using {@code env.dropAsyncError()}.
+ *
+ * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()}
+ */
+ public void flop(String msg) {
+ try {
+ fail(msg);
+ } catch (Throwable t) {
+ asyncErrors.add(t);
+ }
+ }
+
+ /**
+ * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously.
+ * This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required.
+ *
+ * This overload keeps the passed in throwable as the asyncError, instead of creating an AssertionError for this.
+ *
+ * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution.
+ * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly
+ * from the environment using {@code env.dropAsyncError()}.
+ *
+ * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()}
+ */
+ public void flop(Throwable thr, String msg) {
+ try {
+ fail(msg, thr);
+ } catch (Throwable t) {
+ asyncErrors.add(thr);
+ }
+ }
+
+ /**
+ * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously.
+ * This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required.
+ *
+ * This overload keeps the passed in throwable as the asyncError, instead of creating an AssertionError for this.
+ *
+ * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution.
+ * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly
+ * from the environment using {@code env.dropAsyncError()}.
+ *
+ * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()}
+ */
+ public void flop(Throwable thr) {
+ try {
+ fail(thr.getMessage(), thr);
+ } catch (Throwable t) {
+ asyncErrors.add(thr);
+ }
+ }
+
+ /**
+ * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously.
+ *
+ * This method DOES fail the test right away (it tries to, by throwing an AssertionException),
+ * in such it is different from {@link org.reactivestreams.tck.TestEnvironment#flop} which only records the error.
+ *
+ * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution.
+ * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly
+ * from the environment using {@code env.dropAsyncError()}.
+ *
+ * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()}
+ */
+ public <T> T flopAndFail(String msg) {
+ try {
+ fail(msg);
+ } catch (Throwable t) {
+ asyncErrors.add(t);
+ fail(msg, t);
+ }
+ return null; // unreachable, the previous block will always exit by throwing
+ }
+
+
+
+ public <T> void subscribe(Publisher<T> pub, TestSubscriber<T> sub) throws InterruptedException {
+ subscribe(pub, sub, defaultTimeoutMillis);
+ }
+
+ public <T> void subscribe(Publisher<T> pub, TestSubscriber<T> sub, long timeoutMillis) throws InterruptedException {
+ pub.subscribe(sub);
+ sub.subscription.expectCompletion(timeoutMillis, String.format("Could not subscribe %s to Publisher %s", sub, pub));
+ verifyNoAsyncErrorsNoDelay();
+ }
+
+ public <T> ManualSubscriber<T> newBlackholeSubscriber(Publisher<T> pub) throws InterruptedException {
+ ManualSubscriberWithSubscriptionSupport<T> sub = new BlackholeSubscriberWithSubscriptionSupport<T>(this);
+ subscribe(pub, sub, defaultTimeoutMillis());
+ return sub;
+ }
+
+ public <T> ManualSubscriber<T> newManualSubscriber(Publisher<T> pub) throws InterruptedException {
+ return newManualSubscriber(pub, defaultTimeoutMillis());
+ }
+
+ public <T> ManualSubscriber<T> newManualSubscriber(Publisher<T> pub, long timeoutMillis) throws InterruptedException {
+ ManualSubscriberWithSubscriptionSupport<T> sub = new ManualSubscriberWithSubscriptionSupport<T>(this);
+ subscribe(pub, sub, timeoutMillis);
+ return sub;
+ }
+
+ public void clearAsyncErrors() {
+ asyncErrors.clear();
+ }
+
+ public Throwable dropAsyncError() {
+ try {
+ return asyncErrors.remove(0);
+ } catch (IndexOutOfBoundsException ex) {
+ return null;
+ }
+ }
+
+ /**
+ * Waits for {@link TestEnvironment#defaultNoSignalsTimeoutMillis()} and then verifies that no asynchronous errors
+ * were signalled pior to, or during that time (by calling {@code flop()}).
+ */
+ public void verifyNoAsyncErrors() {
+ verifyNoAsyncErrors(defaultNoSignalsTimeoutMillis());
+ }
+
+ /**
+ * This version of {@code verifyNoAsyncErrors} should be used when errors still could be signalled
+ * asynchronously during {@link TestEnvironment#defaultTimeoutMillis()} time.
+ * <p></p>
+ * It will immediatly check if any async errors were signaled (using {@link TestEnvironment#flop(String)},
+ * and if no errors encountered wait for another default timeout as the errors may yet be signalled.
+ * The initial check is performed in order to fail-fast in case of an already failed test.
+ */
+ public void verifyNoAsyncErrors(long delay) {
+ try {
+ verifyNoAsyncErrorsNoDelay();
+
+ Thread.sleep(delay);
+ verifyNoAsyncErrorsNoDelay();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Verifies that no asynchronous errors were signalled pior to calling this method (by calling {@code flop()}).
+ * This version of verifyNoAsyncError <b>does not wait before checking for asynchronous errors</b>, and is to be used
+ * for example in tight loops etc.
+ */
+ public void verifyNoAsyncErrorsNoDelay() {
+ for (Throwable e : asyncErrors) {
+ if (e instanceof AssertionError) {
+ throw (AssertionError) e;
+ } else {
+ fail(String.format("Async error during test execution: %s", e.getMessage()), e);
+ }
+ }
+ }
+
+ /** If {@code TestEnvironment#printlnDebug} is true, print debug message to std out. */
+ public void debug(String msg) {
+ if (debugEnabled()) {
+ System.out.printf("[TCK-DEBUG] %s%n", msg);
+ }
+ }
+
+ public final boolean debugEnabled() {
+ return printlnDebug;
+ }
+
+ /**
+ * Looks for given {@code method} method in stack trace.
+ * Can be used to answer questions like "was this method called from onComplete?".
+ *
+ * @return the caller's StackTraceElement at which he the looked for method was found in the call stack, EMPTY otherwise
+ */
+ public Optional<StackTraceElement> findCallerMethodInStackTrace(String method) {
+ final Throwable thr = new Throwable(); // gets the stacktrace
+
+ for (StackTraceElement stackElement : thr.getStackTrace()) {
+ if (stackElement.getMethodName().equals(method)) {
+ return Optional.of(stackElement);
+ }
+ }
+ return Optional.empty();
+ }
+
+ // ---- classes ----
+
+ /**
+ * {@link Subscriber} implementation which can be steered by test code and asserted on.
+ */
+ public static class ManualSubscriber<T> extends TestSubscriber<T> {
+ Receptacle<T> received;
+
+ public ManualSubscriber(TestEnvironment env) {
+ super(env);
+ received = new Receptacle<T>(this.env);
+ }
+
+ @Override
+ public void onNext(T element) {
+ try {
+ received.add(element);
+ } catch (IllegalStateException ex) {
+ // error message refinement
+ throw new SubscriberBufferOverflowException(
+ String.format("Received more than bufferSize (%d) onNext signals. " +
+ "The Publisher probably emited more signals than expected!",
+ received.QUEUE_SIZE), ex);
+ }
+ }
+
+ @Override
+ public void onComplete() {
+ received.complete();
+ }
+
+ public void request(long elements) {
+ subscription.value().request(elements);
+ }
+
+ public T requestNextElement() throws InterruptedException {
+ return requestNextElement(env.defaultTimeoutMillis());
+ }
+
+ public T requestNextElement(long timeoutMillis) throws InterruptedException {
+ return requestNextElement(timeoutMillis, "Did not receive expected element");
+ }
+
+ public T requestNextElement(String errorMsg) throws InterruptedException {
+ return requestNextElement(env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public T requestNextElement(long timeoutMillis, String errorMsg) throws InterruptedException {
+ request(1);
+ return nextElement(timeoutMillis, errorMsg);
+ }
+
+ public Optional<T> requestNextElementOrEndOfStream() throws InterruptedException {
+ return requestNextElementOrEndOfStream(env.defaultTimeoutMillis(), "Did not receive expected stream completion");
+ }
+
+ public Optional<T> requestNextElementOrEndOfStream(String errorMsg) throws InterruptedException {
+ return requestNextElementOrEndOfStream(env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public Optional<T> requestNextElementOrEndOfStream(long timeoutMillis) throws InterruptedException {
+ return requestNextElementOrEndOfStream(timeoutMillis, "Did not receive expected stream completion");
+ }
+
+ public Optional<T> requestNextElementOrEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException {
+ request(1);
+ return nextElementOrEndOfStream(timeoutMillis, errorMsg);
+ }
+
+ public void requestEndOfStream() throws InterruptedException {
+ requestEndOfStream(env.defaultTimeoutMillis(), "Did not receive expected stream completion");
+ }
+
+ public void requestEndOfStream(long timeoutMillis) throws InterruptedException {
+ requestEndOfStream(timeoutMillis, "Did not receive expected stream completion");
+ }
+
+ public void requestEndOfStream(String errorMsg) throws InterruptedException {
+ requestEndOfStream(env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public void requestEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException {
+ request(1);
+ expectCompletion(timeoutMillis, errorMsg);
+ }
+
+ public List<T> requestNextElements(long elements) throws InterruptedException {
+ request(elements);
+ return nextElements(elements, env.defaultTimeoutMillis());
+ }
+
+ public List<T> requestNextElements(long elements, long timeoutMillis) throws InterruptedException {
+ request(elements);
+ return nextElements(elements, timeoutMillis, String.format("Did not receive %d expected elements", elements));
+ }
+
+ public List<T> requestNextElements(long elements, long timeoutMillis, String errorMsg) throws InterruptedException {
+ request(elements);
+ return nextElements(elements, timeoutMillis, errorMsg);
+ }
+
+ public T nextElement() throws InterruptedException {
+ return nextElement(env.defaultTimeoutMillis());
+ }
+
+ public T nextElement(long timeoutMillis) throws InterruptedException {
+ return nextElement(timeoutMillis, "Did not receive expected element");
+ }
+
+ public T nextElement(String errorMsg) throws InterruptedException {
+ return nextElement(env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public T nextElement(long timeoutMillis, String errorMsg) throws InterruptedException {
+ return received.next(timeoutMillis, errorMsg);
+ }
+
+ public Optional<T> nextElementOrEndOfStream() throws InterruptedException {
+ return nextElementOrEndOfStream(env.defaultTimeoutMillis(), "Did not receive expected stream completion");
+ }
+
+ public Optional<T> nextElementOrEndOfStream(long timeoutMillis) throws InterruptedException {
+ return nextElementOrEndOfStream(timeoutMillis, "Did not receive expected stream completion");
+ }
+
+ public Optional<T> nextElementOrEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException {
+ return received.nextOrEndOfStream(timeoutMillis, errorMsg);
+ }
+
+ public List<T> nextElements(long elements) throws InterruptedException {
+ return nextElements(elements, env.defaultTimeoutMillis(), "Did not receive expected element or completion");
+ }
+
+ public List<T> nextElements(long elements, String errorMsg) throws InterruptedException {
+ return nextElements(elements, env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public List<T> nextElements(long elements, long timeoutMillis) throws InterruptedException {
+ return nextElements(elements, timeoutMillis, "Did not receive expected element or completion");
+ }
+
+ public List<T> nextElements(long elements, long timeoutMillis, String errorMsg) throws InterruptedException {
+ return received.nextN(elements, timeoutMillis, errorMsg);
+ }
+
+ public void expectNext(T expected) throws InterruptedException {
+ expectNext(expected, env.defaultTimeoutMillis());
+ }
+
+ public void expectNext(T expected, long timeoutMillis) throws InterruptedException {
+ T received = nextElement(timeoutMillis, "Did not receive expected element on downstream");
+ if (!received.equals(expected)) {
+ env.flop(String.format("Expected element %s on downstream but received %s", expected, received));
+ }
+ }
+
+ public void expectCompletion() throws InterruptedException {
+ expectCompletion(env.defaultTimeoutMillis(), "Did not receive expected stream completion");
+ }
+
+ public void expectCompletion(long timeoutMillis) throws InterruptedException {
+ expectCompletion(timeoutMillis, "Did not receive expected stream completion");
+ }
+
+ public void expectCompletion(String errorMsg) throws InterruptedException {
+ expectCompletion(env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public void expectCompletion(long timeoutMillis, String errorMsg) throws InterruptedException {
+ received.expectCompletion(timeoutMillis, errorMsg);
+ }
+
+ public <E extends Throwable> void expectErrorWithMessage(Class<E> expected, String requiredMessagePart) throws Exception {
+ expectErrorWithMessage(expected, Collections.singletonList(requiredMessagePart), env.defaultTimeoutMillis(), env.defaultPollTimeoutMillis());
+ }
+ public <E extends Throwable> void expectErrorWithMessage(Class<E> expected, List<String> requiredMessagePartAlternatives) throws Exception {
+ expectErrorWithMessage(expected, requiredMessagePartAlternatives, env.defaultTimeoutMillis(), env.defaultPollTimeoutMillis());
+ }
+
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public <E extends Throwable> void expectErrorWithMessage(Class<E> expected, String requiredMessagePart, long timeoutMillis) throws Exception {
+ expectErrorWithMessage(expected, Collections.singletonList(requiredMessagePart), timeoutMillis);
+ }
+
+ public <E extends Throwable> void expectErrorWithMessage(Class<E> expected, List<String> requiredMessagePartAlternatives, long timeoutMillis) throws Exception {
+ expectErrorWithMessage(expected, requiredMessagePartAlternatives, timeoutMillis, timeoutMillis);
+ }
+
+ public <E extends Throwable> void expectErrorWithMessage(Class<E> expected, List<String> requiredMessagePartAlternatives,
+ long totalTimeoutMillis, long pollTimeoutMillis) throws Exception {
+ final E err = expectError(expected, totalTimeoutMillis, pollTimeoutMillis);
+ final String message = err.getMessage();
+
+ boolean contains = false;
+ for (String requiredMessagePart : requiredMessagePartAlternatives)
+ if (message.contains(requiredMessagePart)) contains = true; // not short-circuting loop, it is expected to
+ assertTrue(contains,
+ String.format("Got expected exception [%s] but missing message part [%s], was: %s",
+ err.getClass(), "anyOf: " + requiredMessagePartAlternatives, err.getMessage()));
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected) throws Exception {
+ return expectError(expected, env.defaultTimeoutMillis());
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected, long timeoutMillis) throws Exception {
+ return expectError(expected, timeoutMillis, env.defaultPollTimeoutMillis());
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected, String errorMsg) throws Exception {
+ return expectError(expected, env.defaultTimeoutMillis(), errorMsg);
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected, long timeoutMillis, String errorMsg) throws Exception {
+ return expectError(expected, timeoutMillis, env.defaultPollTimeoutMillis(), errorMsg);
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected, long totalTimeoutMillis, long pollTimeoutMillis) throws Exception {
+ return expectError(expected, totalTimeoutMillis, pollTimeoutMillis, String.format("Expected onError(%s)", expected.getName()));
+ }
+
+ public <E extends Throwable> E expectError(Class<E> expected, long totalTimeoutMillis, long pollTimeoutMillis,
+ String errorMsg) throws Exception {
+ return received.expectError(expected, totalTimeoutMillis, pollTimeoutMillis, errorMsg);
+ }
+
+ public void expectNone() throws InterruptedException {
+ expectNone(env.defaultNoSignalsTimeoutMillis());
+ }
+
+ public void expectNone(String errMsgPrefix) throws InterruptedException {
+ expectNone(env.defaultNoSignalsTimeoutMillis(), errMsgPrefix);
+ }
+
+ public void expectNone(long withinMillis) throws InterruptedException {
+ expectNone(withinMillis, "Did not expect an element but got element");
+ }
+
+ public void expectNone(long withinMillis, String errMsgPrefix) throws InterruptedException {
+ received.expectNone(withinMillis, errMsgPrefix);
+ }
+
+ }
+
+ public static class ManualSubscriberWithSubscriptionSupport<T> extends ManualSubscriber<T> {
+
+ public ManualSubscriberWithSubscriptionSupport(TestEnvironment env) {
+ super(env);
+ }
+
+ @Override
+ public void onNext(T element) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("%s::onNext(%s)", this, element));
+ }
+ if (subscription.isCompleted()) {
+ super.onNext(element);
+ } else {
+ env.flop(String.format("Subscriber::onNext(%s) called before Subscriber::onSubscribe", element));
+ }
+ }
+
+ @Override
+ public void onComplete() {
+ if (env.debugEnabled()) {
+ env.debug(this + "::onComplete()");
+ }
+ if (subscription.isCompleted()) {
+ super.onComplete();
+ } else {
+ env.flop("Subscriber::onComplete() called before Subscriber::onSubscribe");
+ }
+ }
+
+ @Override
+ public void onSubscribe(Subscription s) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("%s::onSubscribe(%s)", this, s));
+ }
+ if (!subscription.isCompleted()) {
+ subscription.complete(s);
+ } else {
+ env.flop("Subscriber::onSubscribe called on an already-subscribed Subscriber");
+ }
+ }
+
+ @Override
+ public void onError(Throwable cause) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("%s::onError(%s)", this, cause));
+ }
+ if (subscription.isCompleted()) {
+ super.onError(cause);
+ } else {
+ env.flop(cause, String.format("Subscriber::onError(%s) called before Subscriber::onSubscribe", cause));
+ }
+ }
+ }
+
+ /**
+ * Similar to {@link org.reactivestreams.tck.TestEnvironment.ManualSubscriberWithSubscriptionSupport}
+ * but does not accumulate values signalled via <code>onNext</code>, thus it can not be used to assert
+ * values signalled to this subscriber. Instead it may be used to quickly drain a given publisher.
+ */
+ public static class BlackholeSubscriberWithSubscriptionSupport<T>
+ extends ManualSubscriberWithSubscriptionSupport<T> {
+
+ public BlackholeSubscriberWithSubscriptionSupport(TestEnvironment env) {
+ super(env);
+ }
+
+ @Override
+ public void onNext(T element) {
+ if (env.debugEnabled()) {
+ env.debug(String.format("%s::onNext(%s)", this, element));
+ }
+ if (!subscription.isCompleted()) {
+ env.flop(String.format("Subscriber::onNext(%s) called before Subscriber::onSubscribe", element));
+ }
+ }
+
+ @Override
+ public T nextElement(long timeoutMillis, String errorMsg) throws InterruptedException {
+ throw new RuntimeException("Can not expect elements from BlackholeSubscriber, use ManualSubscriber instead!");
+ }
+
+ @Override
+ public List<T> nextElements(long elements, long timeoutMillis, String errorMsg) throws InterruptedException {
+ throw new RuntimeException("Can not expect elements from BlackholeSubscriber, use ManualSubscriber instead!");
+ }
+ }
+
+ public static class TestSubscriber<T> implements Subscriber<T> {
+ final Promise<Subscription> subscription;
+
+ protected final TestEnvironment env;
+
+ public TestSubscriber(TestEnvironment env) {
+ this.env = env;
+ subscription = new Promise<Subscription>(env);
+ }
+
+ @Override
+ public void onError(Throwable cause) {
+ env.flop(cause, String.format("Unexpected Subscriber::onError(%s)", cause));
+ }
+
+ @Override
+ public void onComplete() {
+ env.flop("Unexpected Subscriber::onComplete()");
+ }
+
+ @Override
+ public void onNext(T element) {
+ env.flop(String.format("Unexpected Subscriber::onNext(%s)", element));
+ }
+
+ @Override
+ public void onSubscribe(Subscription subscription) {
+ env.flop(String.format("Unexpected Subscriber::onSubscribe(%s)", subscription));
+ }
+
+ public void cancel() {
+ if (subscription.isCompleted()) {
+ subscription.value().cancel();
+ } else {
+ env.flop("Cannot cancel a subscription before having received it");
+ }
+ }
+ }
+
+ public static class ManualPublisher<T> implements Publisher<T> {
+ protected final TestEnvironment env;
+
+ protected long pendingDemand = 0L;
+ protected Promise<Subscriber<? super T>> subscriber;
+
+ protected final Receptacle<Long> requests;
+
+ protected final Latch cancelled;
+
+ public ManualPublisher(TestEnvironment env) {
+ this.env = env;
+ requests = new Receptacle<Long>(env);
+ cancelled = new Latch(env);
+ subscriber = new Promise<Subscriber<? super T>>(this.env);
+ }
+
+ @Override
+ public void subscribe(Subscriber<? super T> s) {
+ if (!subscriber.isCompleted()) {
+ subscriber.completeImmediatly(s);
+
+ Subscription subs = new Subscription() {
+ @Override
+ public void request(long elements) {
+ requests.add(elements);
+ }
+
+ @Override
+ public void cancel() {
+ cancelled.close();
+ }
+ };
+ s.onSubscribe(subs);
+
+ } else {
+ env.flop("TestPublisher doesn't support more than one Subscriber");
+ }
+ }
+
+ public void sendNext(T element) {
+ if (subscriber.isCompleted()) {
+ subscriber.value().onNext(element);
+ } else {
+ env.flop("Cannot sendNext before having a Subscriber");
+ }
+ }
+
+ public void sendCompletion() {
+ if (subscriber.isCompleted()) {
+ subscriber.value().onComplete();
+ } else {
+ env.flop("Cannot sendCompletion before having a Subscriber");
+ }
+ }
+
+ public void sendError(Throwable cause) {
+ if (subscriber.isCompleted()) {
+ subscriber.value().onError(cause);
+ } else {
+ env.flop("Cannot sendError before having a Subscriber");
+ }
+ }
+
+ public long expectRequest() throws InterruptedException {
+ return expectRequest(env.defaultTimeoutMillis());
+ }
+
+ public long expectRequest(long timeoutMillis) throws InterruptedException {
+ long requested = requests.next(timeoutMillis, "Did not receive expected `request` call");
+ if (requested <= 0) {
+ return env.<Long>flopAndFail(String.format("Requests cannot be zero or negative but received request(%s)", requested));
+ } else {
+ pendingDemand += requested;
+ return requested;
+ }
+ }
+
+
+ public long expectRequest(long timeoutMillis, String errorMessageAddendum) throws InterruptedException {
+ long requested = requests.next(timeoutMillis, String.format("Did not receive expected `request` call. %s", errorMessageAddendum));
+ if (requested <= 0) {
+ return env.<Long>flopAndFail(String.format("Requests cannot be zero or negative but received request(%s)", requested));
+ } else {
+ pendingDemand += requested;
+ return requested;
+ }
+ }
+
+ public void expectExactRequest(long expected) throws InterruptedException {
+ expectExactRequest(expected, env.defaultTimeoutMillis());
+ }
+
+ public void expectExactRequest(long expected, long timeoutMillis) throws InterruptedException {
+ long requested = expectRequest(timeoutMillis);
+ if (requested != expected) {
+ env.flop(String.format("Received `request(%d)` on upstream but expected `request(%d)`", requested, expected));
+ }
+ pendingDemand += requested;
+ }
+
+ public void expectNoRequest() throws InterruptedException {
+ expectNoRequest(env.defaultTimeoutMillis());
+ }
+
+ public void expectNoRequest(long timeoutMillis) throws InterruptedException {
+ requests.expectNone(timeoutMillis, "Received an unexpected call to: request: ");
+ }
+
+ public void expectCancelling() throws InterruptedException {
+ expectCancelling(env.defaultTimeoutMillis());
+ }
+
+ public void expectCancelling(long timeoutMillis) throws InterruptedException {
+ cancelled.expectClose(timeoutMillis, "Did not receive expected cancelling of upstream subscription");
+ }
+
+ public boolean isCancelled() throws InterruptedException {
+ return cancelled.isClosed();
+ }
+ }
+
+ /**
+ * Like a CountDownLatch, but resettable and with some convenience methods
+ */
+ public static class Latch {
+ private final TestEnvironment env;
+ volatile private CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ public Latch(TestEnvironment env) {
+ this.env = env;
+ }
+
+ public void reOpen() {
+ countDownLatch = new CountDownLatch(1);
+ }
+
+ public boolean isClosed() {
+ return countDownLatch.getCount() == 0;
+ }
+
+ public void close() {
+ countDownLatch.countDown();
+ }
+
+ public void assertClosed(String openErrorMsg) {
+ if (!isClosed()) {
+ env.flop(new ExpectedClosedLatchException(openErrorMsg));
+ }
+ }
+
+ public void assertOpen(String closedErrorMsg) {
+ if (isClosed()) {
+ env.flop(new ExpectedOpenLatchException(closedErrorMsg));
+ }
+ }
+
+ public void expectClose(String notClosedErrorMsg) throws InterruptedException {
+ expectClose(env.defaultTimeoutMillis(), notClosedErrorMsg);
+ }
+
+ public void expectClose(long timeoutMillis, String notClosedErrorMsg) throws InterruptedException {
+ countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+ if (countDownLatch.getCount() > 0) {
+ env.flop(String.format("%s within %d ms", notClosedErrorMsg, timeoutMillis));
+ }
+ }
+
+ static final class ExpectedOpenLatchException extends RuntimeException {
+ public ExpectedOpenLatchException(String message) {
+ super(message);
+ }
+ }
+
+ static final class ExpectedClosedLatchException extends RuntimeException {
+ public ExpectedClosedLatchException(String message) {
+ super(message);
+ }
+ }
+
+ }
+
+ // simple promise for *one* value, which cannot be reset
+ public static class Promise<T> {
+ private final TestEnvironment env;
+
+ public static <T> Promise<T> completed(TestEnvironment env, T value) {
+ Promise<T> promise = new Promise<T>(env);
+ promise.completeImmediatly(value);
+ return promise;
+ }
+
+ public Promise(TestEnvironment env) {
+ this.env = env;
+ }
+
+ private ArrayBlockingQueue<T> abq = new ArrayBlockingQueue<T>(1);
+ private AtomicReference<T> _value = new AtomicReference<T>();
+
+ public T value() {
+ final T value = _value.get();
+ if (value != null) {
+ return value;
+ } else {
+ env.flop("Cannot access promise value before completion");
+ return null;
+ }
+ }
+
+ public boolean isCompleted() {
+ return _value.get() != null;
+ }
+
+ /**
+ * Allows using expectCompletion to await for completion of the value and complete it _then_
+ */
+ public void complete(T value) {
+ if (_value.compareAndSet(null, value)) {
+ // we add the value to the queue such to wake up any expectCompletion which was triggered before complete() was called
+ abq.add(value);
+ } else {
+ env.flop(String.format("Cannot complete a promise more than once! Present value: %s, attempted to set: %s", _value.get(), value));
+ }
+ }
+
+ /**
+ * Same as complete.
+ *
+ * Keeping this method for binary compatibility.
+ */
+ public void completeImmediatly(T value) {
+ complete(value);
+ }
+
+ public void expectCompletion(long timeoutMillis, String errorMsg) throws InterruptedException {
+ if (!isCompleted()) {
+ T val = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+
+ if (val == null) {
+ env.flop(String.format("%s within %d ms", errorMsg, timeoutMillis));
+ }
+ }
+ }
+ }
+
+ // a "Promise" for multiple values, which also supports "end-of-stream reached"
+ public static class Receptacle<T> {
+ final int QUEUE_SIZE = 2 * TEST_BUFFER_SIZE;
+ private final TestEnvironment env;
+
+ private final ArrayBlockingQueue<Optional<T>> abq = new ArrayBlockingQueue<Optional<T>>(QUEUE_SIZE);
+
+ private final Latch completedLatch;
+
+ Receptacle(TestEnvironment env) {
+ this.env = env;
+ this.completedLatch = new Latch(env);
+ }
+
+ public void add(T value) {
+ completedLatch.assertOpen(String.format("Unexpected element %s received after stream completed", value));
+
+ abq.add(Optional.of(value));
+ }
+
+ public void complete() {
+ completedLatch.assertOpen("Unexpected additional complete signal received!");
+ completedLatch.close();
+
+ abq.add(Optional.<T>empty());
+ }
+
+ public T next(long timeoutMillis, String errorMsg) throws InterruptedException {
+ Optional<T> value = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+
+ if (value == null) {
+ return env.flopAndFail(String.format("%s within %d ms", errorMsg, timeoutMillis));
+ } else if (value.isDefined()) {
+ return value.get();
+ } else {
+ return env.flopAndFail("Expected element but got end-of-stream");
+ }
+ }
+
+ public Optional<T> nextOrEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException {
+ Optional<T> value = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+
+ if (value == null) {
+ env.flop(String.format("%s within %d ms", errorMsg, timeoutMillis));
+ return Optional.empty();
+ }
+
+ return value;
+ }
+
+ /**
+ * @param timeoutMillis total timeout time for awaiting all {@code elements} number of elements
+ */
+ public List<T> nextN(long elements, long timeoutMillis, String errorMsg) throws InterruptedException {
+ List<T> result = new LinkedList<T>();
+ long remaining = elements;
+ long deadline = System.currentTimeMillis() + timeoutMillis;
+ while (remaining > 0) {
+ long remainingMillis = deadline - System.currentTimeMillis();
+
+ result.add(next(remainingMillis, errorMsg));
+ remaining--;
+ }
+
+ return result;
+ }
+
+
+ public void expectCompletion(long timeoutMillis, String errorMsg) throws InterruptedException {
+ Optional<T> value = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+
+ if (value == null) {
+ env.flop(String.format("%s within %d ms", errorMsg, timeoutMillis));
+ } else if (value.isDefined()) {
+ env.flop(String.format("Expected end-of-stream but got element [%s]", value.get()));
+ } // else, ok
+ }
+
+ /**
+ * @deprecated Deprecated in favor of {@link #expectError(Class, long, long, String)}.
+ */
+ @Deprecated
+ public <E extends Throwable> E expectError(Class<E> clazz, long timeoutMillis, String errorMsg) throws Exception {
+ return expectError(clazz, timeoutMillis, timeoutMillis, errorMsg);
+ }
+
+ @SuppressWarnings("unchecked")
+ final <E extends Throwable> E expectError(Class<E> clazz, final long totalTimeoutMillis,
+ long pollTimeoutMillis,
+ String errorMsg) throws Exception {
+ long totalTimeoutRemainingNs = MILLISECONDS.toNanos(totalTimeoutMillis);
+ long timeStampANs = System.nanoTime();
+ long timeStampBNs;
+
+ for (;;) {
+ Thread.sleep(Math.min(pollTimeoutMillis, NANOSECONDS.toMillis(totalTimeoutRemainingNs)));
+
+ if (env.asyncErrors.isEmpty()) {
+ timeStampBNs = System.nanoTime();
+ totalTimeoutRemainingNs =- timeStampBNs - timeStampANs;
+ timeStampANs = timeStampBNs;
+
+ if (totalTimeoutRemainingNs <= 0) {
+ return env.flopAndFail(String.format("%s within %d ms", errorMsg, totalTimeoutMillis));
+ }
+ } else {
+ // ok, there was an expected error
+ Throwable thrown = env.asyncErrors.remove(0);
+
+ if (clazz.isInstance(thrown)) {
+ return (E) thrown;
+ } else {
+
+ return env.flopAndFail(String.format("%s within %d ms; Got %s but expected %s",
+ errorMsg, totalTimeoutMillis, thrown.getClass().getCanonicalName(), clazz.getCanonicalName()));
+ }
+ }
+ }
+ }
+
+ public void expectNone(long withinMillis, String errorMsgPrefix) throws InterruptedException {
+ Thread.sleep(withinMillis);
+ Optional<T> value = abq.poll();
+
+ if (value == null) {
+ // ok
+ } else if (value.isDefined()) {
+ env.flop(String.format("%s [%s]", errorMsgPrefix, value.get()));
+ } else {
+ env.flop("Expected no element but got end-of-stream");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/WithHelperPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.tck.flow.support.Function;
+import org.reactivestreams.tck.flow.support.HelperPublisher;
+import org.reactivestreams.tck.flow.support.InfiniteHelperPublisher;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Type which is able to create elements based on a seed {@code id} value.
+ * <p>
+ * Simplest implementations will simply return the incoming id as the element.
+ *
+ * @param <T> type of element to be delivered to the Subscriber
+ */
+public abstract class WithHelperPublisher<T> {
+
+ /** ExecutorService to be used by the provided helper {@link org.reactivestreams.Publisher} */
+ public abstract ExecutorService publisherExecutorService();
+
+ /**
+ * Implement this method to match your expected element type.
+ * In case of implementing a simple Subscriber which is able to consume any kind of element simply return the
+ * incoming {@code element} element.
+ * <p>
+ * Sometimes the Subscriber may be limited in what type of element it is able to consume, this you may have to implement
+ * this method such that the emitted element matches the Subscribers requirements. Simplest implementations would be
+ * to simply pass in the {@code element} as payload of your custom element, such as appending it to a String or other identifier.
+ * <p>
+ * <b>Warning:</b> This method may be called concurrently by the helper publisher, thus it should be implemented in a
+ * thread-safe manner.
+ *
+ * @return element of the matching type {@code T} that will be delivered to the tested Subscriber
+ */
+ public abstract T createElement(int element);
+
+ /**
+ * Helper method required for creating the Publisher to which the tested Subscriber will be subscribed and tested against.
+ * <p>
+ * By default an <b>asynchronously signalling Publisher</b> is provided, which will use {@link #createElement(int)}
+ * to generate elements type your Subscriber is able to consume.
+ * <p>
+ * Sometimes you may want to implement your own custom custom helper Publisher - to validate behaviour of a Subscriber
+ * when facing a synchronous Publisher for example. If you do, it MUST emit the exact number of elements asked for
+ * (via the {@code elements} parameter) and MUST also must treat the following numbers of elements in these specific ways:
+ * <ul>
+ * <li>
+ * If {@code elements} is {@code Long.MAX_VALUE} the produced stream must be infinite.
+ * </li>
+ * <li>
+ * If {@code elements} is {@code 0} the {@code Publisher} should signal {@code onComplete} immediatly.
+ * In other words, it should represent a "completed stream".
+ * </li>
+ * </ul>
+ */
+ @SuppressWarnings("unchecked")
+ public Publisher<T> createHelperPublisher(long elements) {
+ final Function<Integer, T> mkElement = new Function<Integer, T>() {
+ @Override public T apply(Integer id) throws Throwable {
+ return createElement(id);
+ }
+ };
+
+ if (elements > Integer.MAX_VALUE) return new InfiniteHelperPublisher(mkElement, publisherExecutorService());
+ else return new HelperPublisher(0, (int) elements, mkElement, publisherExecutorService());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowPublisherVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow;
+
+import org.reactivestreams.Publisher;
+import org.reactivestreams.FlowAdapters;
+import org.reactivestreams.tck.PublisherVerification;
+import org.reactivestreams.tck.TestEnvironment;
+
+import java.util.concurrent.Flow;
+
+/**
+ * Provides tests for verifying a Java 9+ {@link java.util.concurrent.Flow.Publisher} specification rules.
+ *
+ * @see java.util.concurrent.Flow.Publisher
+ */
+public abstract class FlowPublisherVerification<T> extends PublisherVerification<T> {
+
+ public FlowPublisherVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis) {
+ super(env, publisherReferenceGCTimeoutMillis);
+ }
+
+ public FlowPublisherVerification(TestEnvironment env) {
+ super(env);
+ }
+
+ @Override
+ final public Publisher<T> createPublisher(long elements) {
+ final Flow.Publisher<T> flowPublisher = createFlowPublisher(elements);
+ return FlowAdapters.toPublisher(flowPublisher);
+ }
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a Publisher for a stream with exactly the given number of elements.
+ * If `elements` is `Long.MAX_VALUE` the produced stream must be infinite.
+ */
+ public abstract Flow.Publisher<T> createFlowPublisher(long elements);
+
+ @Override
+ final public Publisher<T> createFailedPublisher() {
+ final Flow.Publisher<T> failed = createFailedFlowPublisher();
+ if (failed == null) return null; // because `null` means "SKIP" in createFailedPublisher
+ else return FlowAdapters.toPublisher(failed);
+ }
+ /**
+ * By implementing this method, additional TCK tests concerning a "failed" publishers will be run.
+ *
+ * The expected behaviour of the {@link Flow.Publisher} returned by this method is hand out a subscription,
+ * followed by signalling {@code onError} on it, as specified by Rule 1.9.
+ *
+ * If you ignore these additional tests, return {@code null} from this method.
+ */
+ public abstract Flow.Publisher<T> createFailedFlowPublisher();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberBlackboxVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow;
+
+import org.reactivestreams.FlowAdapters;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.Subscription;
+import org.reactivestreams.tck.SubscriberBlackboxVerification;
+import org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.support.SubscriberBlackboxVerificationRules;
+
+import java.util.concurrent.Flow;
+
+/**
+ * Provides tests for verifying {@link java.util.concurrent.Flow.Subscriber} and {@link java.util.concurrent.Flow.Subscription}
+ * specification rules, without any modifications to the tested implementation (also known as "Black Box" testing).
+ *
+ * This verification is NOT able to check many of the rules of the spec, and if you want more
+ * verification of your implementation you'll have to implement {@code org.reactivestreams.tck.SubscriberWhiteboxVerification}
+ * instead.
+ *
+ * @see java.util.concurrent.Flow.Subscriber
+ * @see java.util.concurrent.Flow.Subscription
+ */
+public abstract class FlowSubscriberBlackboxVerification<T> extends SubscriberBlackboxVerification<T>
+ implements SubscriberBlackboxVerificationRules {
+
+ protected FlowSubscriberBlackboxVerification(TestEnvironment env) {
+ super(env);
+ }
+
+ @Override
+ public final void triggerRequest(Subscriber<? super T> subscriber) {
+ triggerFlowRequest(FlowAdapters.toFlowSubscriber(subscriber));
+ }
+ /**
+ * Override this method if the {@link java.util.concurrent.Flow.Subscriber} implementation you are verifying
+ * needs an external signal before it signals demand to its Publisher.
+ *
+ * By default this method does nothing.
+ */
+ public void triggerFlowRequest(Flow.Subscriber<? super T> subscriber) {
+ // this method is intentionally left blank
+ }
+
+ @Override
+ public final Subscriber<T> createSubscriber() {
+ return FlowAdapters.<T>toSubscriber(createFlowSubscriber());
+ }
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a new {@link Flow.Subscriber} instance to be subjected to the testing logic.
+ */
+ abstract public Flow.Subscriber<T> createFlowSubscriber();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberWhiteboxVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow;
+
+import org.reactivestreams.FlowAdapters;
+import org.reactivestreams.Subscriber;
+import org.reactivestreams.tck.SubscriberWhiteboxVerification;
+import org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules;
+
+import java.util.concurrent.Flow;
+
+/**
+ * Provides whitebox style tests for verifying {@link java.util.concurrent.Flow.Subscriber}
+ * and {@link java.util.concurrent.Flow.Subscription} specification rules.
+ *
+ * @see java.util.concurrent.Flow.Subscriber
+ * @see java.util.concurrent.Flow.Subscription
+ */
+public abstract class FlowSubscriberWhiteboxVerification<T> extends SubscriberWhiteboxVerification<T>
+ implements SubscriberWhiteboxVerificationRules {
+
+ protected FlowSubscriberWhiteboxVerification(TestEnvironment env) {
+ super(env);
+ }
+
+ @Override
+ final public Subscriber<T> createSubscriber(WhiteboxSubscriberProbe<T> probe) {
+ return FlowAdapters.toSubscriber(createFlowSubscriber(probe));
+ }
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a new {@link org.reactivestreams.Subscriber} instance to be subjected to the testing logic.
+ *
+ * In order to be meaningfully testable your Subscriber must inform the given
+ * `WhiteboxSubscriberProbe` of the respective events having been received.
+ */
+ protected abstract Flow.Subscriber<T> createFlowSubscriber(WhiteboxSubscriberProbe<T> probe);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/IdentityFlowProcessorVerification.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow;
+
+import org.reactivestreams.*;
+import org.reactivestreams.tck.IdentityProcessorVerification;
+import org.reactivestreams.tck.TestEnvironment;
+import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules;
+import org.reactivestreams.tck.flow.support.PublisherVerificationRules;
+
+import java.util.concurrent.Flow;
+
+public abstract class IdentityFlowProcessorVerification<T> extends IdentityProcessorVerification<T>
+ implements SubscriberWhiteboxVerificationRules, PublisherVerificationRules {
+
+ public IdentityFlowProcessorVerification(TestEnvironment env) {
+ super(env);
+ }
+
+ public IdentityFlowProcessorVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis) {
+ super(env, publisherReferenceGCTimeoutMillis);
+ }
+
+ public IdentityFlowProcessorVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis, int processorBufferSize) {
+ super(env, publisherReferenceGCTimeoutMillis, processorBufferSize);
+ }
+
+ /**
+ * By implementing this method, additional TCK tests concerning a "failed" Flow publishers will be run.
+ *
+ * The expected behaviour of the {@link Flow.Publisher} returned by this method is hand out a subscription,
+ * followed by signalling {@code onError} on it, as specified by Rule 1.9.
+ *
+ * If you want to ignore these additional tests, return {@code null} from this method.
+ */
+ protected abstract Flow.Publisher<T> createFailedFlowPublisher();
+
+ /**
+ * This is the main method you must implement in your test incarnation.
+ * It must create a {@link Flow.Processor}, which simply forwards all stream elements from its upstream
+ * to its downstream. It must be able to internally buffer the given number of elements.
+ *
+ * @param bufferSize number of elements the processor is required to be able to buffer.
+ */
+ protected abstract Flow.Processor<T,T> createIdentityFlowProcessor(int bufferSize);
+
+ @Override
+ public final Processor<T, T> createIdentityProcessor(int bufferSize) {
+ return FlowAdapters.toProcessor(createIdentityFlowProcessor(bufferSize));
+ }
+
+ @Override
+ public final Publisher<T> createFailedPublisher() {
+ Flow.Publisher<T> failed = createFailedFlowPublisher();
+ if (failed == null) return null; // because `null` means "SKIP" in createFailedPublisher
+ else return FlowAdapters.toPublisher(failed);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Function.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+public interface Function<In, Out> {
+ public Out apply(In in) throws Throwable;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/HelperPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+
+import org.reactivestreams.example.unicast.AsyncIterablePublisher;
+
+public class HelperPublisher<T> extends AsyncIterablePublisher<T> {
+
+ public HelperPublisher(final int from, final int to, final Function<Integer, T> create, final Executor executor) {
+ super(new Iterable<T>() {
+ { if(from > to) throw new IllegalArgumentException("from must be equal or greater than to!"); }
+ @Override public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ private int at = from;
+ @Override public boolean hasNext() { return at < to; }
+ @Override public T next() {
+ if (!hasNext()) return Collections.<T>emptyList().iterator().next();
+ else try {
+ return create.apply(at++);
+ } catch (Throwable t) {
+ throw new IllegalStateException(String.format("Failed to create element for id %d!", at - 1), t);
+ }
+ }
+ @Override public void remove() { throw new UnsupportedOperationException(); }
+ };
+ }
+ }, executor);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/InfiniteHelperPublisher.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+import org.reactivestreams.example.unicast.AsyncIterablePublisher;
+
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+
+public class InfiniteHelperPublisher<T> extends AsyncIterablePublisher<T> {
+
+ public InfiniteHelperPublisher(final Function<Integer, T> create, final Executor executor) {
+ super(new Iterable<T>() {
+ @Override public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ private int at = 0;
+
+ @Override public boolean hasNext() { return true; }
+ @Override public T next() {
+ try {
+ return create.apply(at++); // Wraps around on overflow
+ } catch (Throwable t) {
+ throw new IllegalStateException(
+ String.format("Failed to create element in %s for id %s!", getClass().getSimpleName(), at - 1), t);
+ }
+ }
+ @Override public void remove() { throw new UnsupportedOperationException(); }
+ };
+ }
+ }, executor);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/NonFatal.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+
+/**
+ * Copy of scala.control.util.NonFatal in order to not depend on scala-library
+ */
+public class NonFatal {
+ private NonFatal() {
+ // no instances, please.
+ }
+
+ /**
+ * Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal
+ *
+ * @param t throwable to be matched for fatal-ness
+ * @return true if is a non-fatal throwable, false otherwise
+ */
+ public static boolean isNonFatal(Throwable t) {
+ if (t instanceof StackOverflowError) {
+ // StackOverflowError ok even though it is a VirtualMachineError
+ return true;
+ } else if (t instanceof VirtualMachineError ||
+ t instanceof ThreadDeath ||
+ t instanceof InterruptedException ||
+ t instanceof LinkageError) {
+ // VirtualMachineError includes OutOfMemoryError and other fatal errors
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Optional.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+import java.util.NoSuchElementException;
+
+// simplest possible version of Scala's Option type
+public abstract class Optional<T> {
+
+ private static final Optional<Object> NONE = new Optional<Object>() {
+ @Override
+ public Object get() {
+ throw new NoSuchElementException(".get call on None!");
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+ };
+
+ private Optional() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Optional<T> empty() {
+ return (Optional<T>) NONE;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Optional<T> of(T it) {
+ if (it == null) return (Optional<T>) Optional.NONE;
+ else return new Some(it);
+ }
+
+ public abstract T get();
+
+ public abstract boolean isEmpty();
+
+ public boolean isDefined() {
+ return !isEmpty();
+ }
+
+ public static class Some<T> extends Optional<T> {
+ private final T value;
+
+ Some(T value) {
+ this.value = value;
+ }
+
+ @Override
+ public T get() {
+ return value;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Some(%s)", value);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "None";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/PublisherVerificationRules.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+/**
+ * Internal TCK use only.
+ * Add / Remove tests for PublisherVerification here to make sure that they arre added/removed in the other places.
+ */
+public interface PublisherVerificationRules {
+ /**
+ * Validates that the override of {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()}
+ * returns a non-negative value.
+ */
+ void required_validate_maxElementsFromPublisher() throws Exception;
+ /**
+ * Validates that the override of {@link org.reactivestreams.tck.PublisherVerification#boundedDepthOfOnNextAndRequestRecursion()}
+ * returns a positive value.
+ */
+ void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception;
+ /**
+ * Asks for a {@code Publisher} that should emit exactly one item and complete (both within a
+ * timeout specified by {@link org.reactivestreams.tck.TestEnvironment#defaultTimeoutMillis()})
+ * in response to a request(1).
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} returns zero.
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher},
+ * that {@code Publisher} is actually subscribed to,</li>
+ * <li>if the {@code Publisher} is part of a chain, all elements actually issue a {@code request()} call
+ * in response to the test subscriber or by default to their upstream,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called
+ * as part of the preparation process (usually before subscribing to other {@code Publisher}s),</li>
+ * <li>if the {@code Publisher} implementation works for a consumer that calls {@code request(1)},</li>
+ * <li>if the {@code Publisher} implementation is able to emit an {@code onComplete} without requests,</li>
+ * <li>that the {@code Publisher} implementation does not emit more than the allowed elements (exactly one).</li>
+ * </ul>
+ */
+ void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable;
+ /**
+ * Asks for a {@code Publisher} that should emit exactly three items and complete (all within a
+ * timeout specified by {@link org.reactivestreams.tck.TestEnvironment#defaultTimeoutMillis()}).
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * The tests requests one-by-one and verifies each single response item arrives in time.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher},
+ * that {@code Publisher} is actually subscribed to,</li>
+ * <li>if the {@code Publisher} is part of a chain, all elements actually issue a {@code request()} call
+ * in response to the test subscriber or by default to their upstream,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called
+ * as part of the preparation process (usually before subscribing to other {@code Publisher}s),</li>
+ * <li>if the {@code Publisher} implementation works for a subscriber that calls {@code request(1)} after consuming an item,</li>
+ * <li>if the {@code Publisher} implementation is able to emit an {@code onComplete} without requests.</li>
+ * </ul>
+ */
+ void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable;
+ /**
+ * Asks for a {@code Publisher} that responds to a request pattern of 0 (not requesting upfront), 1, 1 and 2
+ * in a timely manner.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.1'>1.1</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 5.
+ * <p>
+ * This test ensures that the {@code Publisher} implementation correctly responds to {@code request()} calls that in
+ * total are less than the number of elements this {@code Publisher} could emit (thus the completion event won't be emitted).
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} and verifies that requesting once and with more than the length (but bounded) results in the
+ * correct number of items to be emitted (i.e., length 3 and request 10) followed by an {@code onComplete} signal.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.2'>1.2</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * This test ensures that the {@code Publisher} implementation can deal with larger requests than the number of items it can produce.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass.</li>
+ * </ul>
+ */
+ void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (i.e., length 10), repeatedly subscribes to this {@code Publisher}, requests items
+ * one by one and verifies the {@code Publisher} calls the {@code onXXX} methods non-overlappingly.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.3'>1.3</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10.
+ * <p>
+ * Note that this test is probabilistic, that is, may not capture any concurrent invocation in a {code Publisher} implementation.
+ * Note also that this test is sensitive to cases when a {@code request()} call in {@code onSubscribe()} triggers an asynchronous
+ * call to the other {@code onXXX} methods. In contrast, the test allows synchronous call chain of
+ * {@code onSubscribe -> request -> onNext}.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if a {@code request()} call from {@code onSubscribe()} could trigger an asynchronous call to {@code onNext()} and if so, make sure
+ * such {@code request()} calls are deferred until the call to {@code onSubscribe()} returns normally.</li>
+ * </ul>
+ */
+ void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable;
+ /**
+ * Asks for an error {@code Publisher} that should call {@code onSubscribe} exactly once
+ * followed by a single call to {@code onError()} without receiving any requests and otherwise
+ * not throwing any exception.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.4'>1.4</a>
+ * <p>
+ * The test is not executed if {@code PublisherVerification.createErrorPublisher()} returns null.
+ * <p>
+ * If this test fails, the following could be checked within the error {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher},
+ * that {@code Publisher} is actually subscribed to,</li>
+ * <li>if the {@code Publisher} implementation does signal an {@code onSubscribe} before signalling {@code onError},</li>
+ * <li>if the {@code Publisher} implementation is able to emit an {@code onError} without requests,</li>
+ * <li>if the {@code Publisher} is non-empty as this test requires a {@code Publisher} to signal an
+ * {@code onError} eagerly.</li>
+ * </ul>
+ */
+ void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (i.e., length 3) and verifies, after requesting one by one, the sequence
+ * completes normally.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.5'>1.5</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * Note that the tests requests 1 after the items have been received and before expecting an {@code onComplete} signal.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * </ul>
+ */
+ void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable;
+ /**
+ * Asks for an empty {@code Publisher} (i.e., length 0) and verifies it completes in a timely manner.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.5'>1.5</a>
+ * <p>
+ * Note that the tests requests 1 before expecting an {@code onComplete} signal.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>if the {@code Publisher} is non-empty as this test requires a {@code Publisher} without items.</li>
+ * </ul>
+ */
+ void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable;
+ /**
+ * Currently, this test is skipped because it is unclear this rule can be effectively checked
+ * on a {@code Publisher} instance without looking into or hooking into the implementation of it.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.6'>1.6</a>
+ */
+ void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable;
+ /**
+ * Asks for a single-element {@code Publisher} and checks if requesting after the terminal event doesn't
+ * lead to more items or terminal signals to be emitted.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.7'>1.7</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1.
+ * <p>
+ * The tests requests more items than the expected {@code Publisher} length upfront and some more items after its completion.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>the indication for the terminal state is properly persisted and a request call can't trigger emission of more items or another
+ * terminal signal.</li>
+ * </ul>
+ */
+ void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable;
+ /**
+ * Currently, this test is skipped, although it is possible to validate an error {@code Publisher} along
+ * the same lines as {@link #required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled()}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.7'>1.7</a>
+ */
+ void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable;
+ /**
+ * Currently, this test is skipped because there was no agreement on how to verify its "eventually" requirement.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.8'>1.8</a>
+ */
+ void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable;
+ /**
+ * Asks for an empty {@code Publisher} and verifies if {@code onSubscribe} signal was emitted before
+ * any other {@code onNext}, {@code onError} or {@code onComplete} signal.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a>
+ * <p>
+ * Note that this test doesn't request anything, however, an {@code onNext} is not considered as a failure.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher},
+ * that {@code Publisher} is actually subscribed to,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called
+ * as part of the preparation process (usually before subscribing to other {@code Publisher}s).</li>
+ * </ul>
+ */
+ void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable;
+ /**
+ * Currently, this test is skipped because there is no common agreement on what is to be considered a fatal exception and
+ * besides, {@code Publisher.subscribe} is only allowed throw a {@code NullPointerException} and any other
+ * exception would require looking into or hooking into the implementation of the {@code Publisher}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a>
+ */
+ void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable;
+ /**
+ * Asks for an empty {@code Publisher} and calls {@code subscribe} on it with {@code null} that should result in
+ * a {@code NullPointerException} to be thrown.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a>
+ * <p>
+ * If this test fails, check if the {@code subscribe()} implementation has an explicit null check (or a method dereference
+ * on the {@code Subscriber}), especially if the incoming {@code Subscriber} is wrapped or stored to be used later.
+ */
+ void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable;
+ /**
+ * Asks for an error {@code Publisher} that should call {@code onSubscribe} exactly once
+ * followed by a single call to {@code onError()} without receiving any requests.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a>
+ * <p>
+ * The test is not executed if {@code PublisherVerification.createErrorPublisher()} returns null.
+ * <p>
+ * The difference between this test and {@link #optional_spec104_mustSignalOnErrorWhenFails()} is that there is
+ * no explicit verification if exceptions were thrown in addition to the regular {@code onSubscribe+onError} signal pair.
+ * <p>
+ * If this test fails, the following could be checked within the error {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li>
+ * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher},
+ * that {@code Publisher} is actually subscribed to,</li>
+ * <li>if the {@code Publisher} implementation is able to emit an {@code onError} without requests,</li>
+ * <li>if the {@code Publisher} is non-empty as this test expects a {@code Publisher} without items.</li>
+ * </ul>
+ */
+ void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable;
+ /**
+ * Currently, this test is skipped because enforcing rule §1.10 requires unlimited retention and reference-equal checks on
+ * all incoming {@code Subscriber} which is generally infeasible, plus reusing the same {@code Subscriber} instance is
+ * better detected (or ignored) inside {@code Subscriber.onSubscribe} when the method is called multiple times.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.10'>1.10</a>
+ */
+ void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable;
+ /**
+ * Asks for a single-element {@code Publisher} and subscribes to it twice, without consuming with either
+ * {@code Subscriber} instance
+ * (i.e., no requests are issued).
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1.
+ * <p>
+ * Note that this test ignores what signals the {@code Publisher} emits. Any exception thrown through non-regular
+ * means will indicate a skipped test.
+ */
+ void optional_spec111_maySupportMultiSubscribe() throws Throwable;
+ /**
+ * Asks for a single-element {@code Publisher} and subscribes to it twice.
+ * Each {@code Subscriber} requests for 1 element and checks if onNext or onComplete signals was received.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a>,
+ * and depends on valid implementation of rule <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.5'>1.5</a>
+ * in order to verify this.
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1.
+ * <p>
+ * Any exception thrown through non-regular means will indicate a skipped test.
+ */
+ void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 5), subscribes 3 {@code Subscriber}s to it, requests with different
+ * patterns and checks if all 3 received the same events in the same order.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 5.
+ * <p>
+ * The request pattern for the first {@code Subscriber} is (1, 1, 2, 1); for the second is (2, 3) and for the third is (3, 1, 1).
+ * <p>
+ * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of
+ * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test.
+ * <p>
+ * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher},
+ * see the skip message for an indication of this.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 3), subscribes 3 {@code Subscriber}s to it, requests more than the length items
+ * upfront with each and verifies they all received the same items in the same order (but does not verify they all complete).
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of
+ * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test.
+ * <p>
+ * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher},
+ * see the skip message for an indication of this.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 3), subscribes 3 {@code Subscriber}s to it, requests more than the length items
+ * upfront with each and verifies they all received the same items in the same order followed by an {@code onComplete} signal.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of
+ * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test.
+ * <p>
+ * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher},
+ * see the skip message for an indication of this.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 6), requests several times from within {@code onSubscribe} and then requests
+ * one-by-one from {@code onNext}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.2'>3.2</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 6.
+ * <p>
+ * The request pattern is 3 x 1 from within {@code onSubscribe} and one from within each {@code onNext} invocation.
+ * <p>
+ * The test consumes the {@code Publisher} but otherwise doesn't verify the {@code Publisher} completes (however, it checks
+ * for errors).
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable;
+ /**
+ * Asks for a {@code Publisher} with length equal to the value returned by {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()} plus 1,
+ * calls {@code request(1)} externally and then from within {@code onNext} and checks if the stack depth did not increase beyond the
+ * amount permitted by {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.3'>3.3</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than
+ * {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()} plus 1.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the implementation doesn't allow unbounded recursion when {@code request()} is called from within {@code onNext}, i.e., the lack of
+ * reentrant-safe state machine around the request amount (such as a for loop with a bound on the parameter {@code n} that calls {@code onNext}).
+ * </ul>
+ */
+ void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable;
+ /**
+ * Currently, this test is skipped because a {@code request} could enter into a synchronous computation via {@code onNext}
+ * legally and otherwise there is no common agreement how to detect such heavy computation reliably.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.4'>3.4</a>
+ */
+ void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception;
+ /**
+ * Currently, this test is skipped because there is no reliable agreed upon way to detect a heavy computation.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.5'>3.5</a>
+ */
+ void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception;
+ /**
+ * Asks for a short {@code Publisher} (length 3) and verifies that cancelling without requesting anything, then requesting
+ * items should result in no signals to be emitted.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.6'>3.6</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * The post-cancellation request pattern is (1, 1, 1).
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li>
+ * </ul>
+ */
+ void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable;
+ /**
+ * Asks for a single-element {@code Publisher} and verifies that without requesting anything, cancelling the sequence
+ * multiple times should result in no signals to be emitted and should result in an thrown exception.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.7'>3.7</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li>
+ * </ul>
+ */
+ void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 10) and issues a {@code request(0)} which should trigger an {@code onError} call
+ * with an {@code IllegalArgumentException}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.9'>3.9</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10.
+ * <p>
+ * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by
+ * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the
+ * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example).
+ * <p>
+ * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within
+ * the {@code Publisher}.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal
+ * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError}
+ * in general.
+ * </ul>
+ */
+ void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 10) and issues a random, negative {@code request()} call which should
+ * trigger an {@code onError} call with an {@code IllegalArgumentException}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.9'>3.9</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10.
+ * <p>
+ * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by
+ * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the
+ * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example).
+ * <p>
+ * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within
+ * the {@code Publisher}.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal
+ * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError}
+ * in general.
+ * </ul>
+ */
+ void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 10) and issues a random, negative {@code request()} call which should
+ * trigger an {@code onError} call with an {@code IllegalArgumentException}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.9'>3.9</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10.
+ * <p>
+ * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by
+ * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the
+ * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example).
+ * <p>
+ * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within
+ * the {@code Publisher}.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal
+ * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError}
+ * in general.
+ * </ul>
+ */
+ void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 20), requests some items (less than the length), consumes one item then
+ * cancels the sequence and verifies the publisher emitted at most the requested amount and stopped emitting (or terminated).
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.12'>3.12</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 20.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li>
+ * </ul>
+ */
+ void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 3) requests and consumes one element from it, cancels the {@code Subscription}
+ * , calls {@code System.gc()} and then checks if all references to the test {@code Subscriber} has been dropped (by checking
+ * the {@code WeakReference} has been emptied).
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.13'>3.13</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li>
+ * <li>the {@code Publisher} stores the {@code Subscriber} reference somewhere which is then not cleaned up when the {@code Subscriber} is cancelled.
+ * Note that this may happen on many code paths in a {@code Publisher}, for example in an emission loop that terminates because of the
+ * {@code cancel} signal or because reaching a terminal state. Note also that eagerly nulling {@code Subscriber} references may not be necessary
+ * for this test to pass in case there is a self-contained chain of them (i.e., {@code Publisher.subscribe()} creates a chain of fresh
+ * {@code Subscriber} instances where each of them only references their downstream {@code Subscriber} thus the chain can get GC'd
+ * when the reference to the final {@code Subscriber} is dropped).
+ * </ul>
+ */
+ void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 3) and requests {@code Long.MAX_VALUE} from it, verifying that the
+ * {@code Publisher} emits all of its items and completes normally
+ * and does not keep spinning attempting to fulfill the {@code Long.MAX_VALUE} demand by some means.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.17'>3.17</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable;
+ /**
+ * Asks for a short {@code Publisher} (length 3) and requests {@code Long.MAX_VALUE} from it in total (split across
+ * two {@code Long.MAX_VALUE / 2} and one {@code request(1)}), verifying that the
+ * {@code Publisher} emits all of its items and completes normally.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.17'>3.17</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} implements adding individual request amounts together properly (not overflowing into zero or negative pending request amounts)
+ * or not properly deducing the number of emitted items from the pending amount,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable;
+ /**
+ * Asks for a very long {@code Publisher} (up to {@code Integer.MAX_VALUE}), requests {@code Long.MAX_VALUE - 1} after
+ * each received item and expects no failure due to a potential overflow in the pending emission count while consuming
+ * 10 items and cancelling the sequence.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.17'>3.17</a>
+ * <p>
+ * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than {@code Integer.MAX_VALUE}.
+ * <p>
+ * The request pattern is one {@code request(1)} upfront and ten {@code request(Long.MAX_VALUE - 1)} after.
+ * <p>
+ * If this test fails, the following could be checked within the {@code Publisher} implementation:
+ * <ul>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li>
+ * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li>
+ * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li>
+ * <li>if the {@code Publisher} implements adding individual request amounts together properly (not overflowing into zero or negative pending request amounts)
+ * or not properly deducing the number of emitted items from the pending amount,</li>
+ * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li>
+ * </ul>
+ */
+ void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBlackboxVerificationRules.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+import org.reactivestreams.tck.SubscriberBlackboxVerification;
+
+/**
+ * Internal TCK use only.
+ * Add / Remove tests for SubscriberBlackboxVerification here to make sure that they arre added/removed in the other places.
+ */
+public interface SubscriberBlackboxVerificationRules {
+ /**
+ * Asks for a {@code Subscriber} instance, expects it to call {@code request()} in
+ * a timely manner and signals as many {@code onNext} items as the very first request
+ * amount specified by the {@code Subscriber}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.1'>2.1</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>This test emits the number of items requested thus the {@code Subscriber} implementation
+ * should not request too much.</li>
+ * <li>Only the very first {@code request} amount is considered.</li>
+ * <li>This test doesn't signal {@code onComplete} after the first set of {@code onNext} signals
+ * has been emitted and may cause resource leak in
+ * {@code Subscriber}s that expect a finite {@code Publisher}.</li>
+ * <li>The test ignores cancellation from the {@code Subscriber} and emits the requested amount regardless.</li>
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} requires external stimulus to begin requesting; override the
+ * {@link SubscriberBlackboxVerification#triggerRequest(org.reactivestreams.Subscriber)} method
+ * in this case,</li>
+ * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Subscriber} has some time-delay behavior,</li>
+ * <li>if the {@code Subscriber} requests zero or a negative value in some circumstances,</li>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onNext} methods.
+ * </ul>
+ */
+ void required_spec201_blackbox_mustSignalDemandViaSubscriptionRequest() throws Throwable;
+ /**
+ * Currently, this test is skipped because there is no agreed upon approach how
+ * to detect if the {@code Subscriber} really goes async or just responds in
+ * a timely manner.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.2'>2.2</a>
+ */
+ void untested_spec202_blackbox_shouldAsynchronouslyDispatch() throws Exception;
+ /**
+ * Asks for a {@code Subscriber}, signals an {@code onSubscribe} followed by an {@code onComplete} synchronously,
+ * and checks if neither {@code request} nor {@code cancel} was called from within the {@code Subscriber}'s
+ * {@code onComplete} implementation.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.3'>2.3</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The test checks for the presensce of method named "onComplete" in the current stacktrace when handling
+ * the {@code request} or {@code cancel} calls in the test's own {@code Subscription}.
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>no calls happen to {@code request} or {@code cancel} in response to an {@code onComplete}
+ * directly or indirectly,</li>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onComplete} methods.
+ * </ul>
+ */
+ void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable;
+ /**
+ * Asks for a {@code Subscriber}, signals an {@code onSubscribe} followed by an {@code onError} synchronously,
+ * and checks if neither {@code request} nor {@code cancel} was called from within the {@code Subscriber}'s
+ * {@code onComplete} implementation.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.3'>2.3</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The test checks for the presensce of method named "onError" in the current stacktrace when handling
+ * the {@code request} or {@code cancel} calls in the test's own {@code Subscription}.
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>no calls happen to {@code request} or {@code cancel} in response to an {@code onError}
+ * directly or indirectly,</li>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onError} methods.
+ * </ul>
+ */
+ void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable;
+ /**
+ * Currently, this test is skipped because there is no way to check what the {@code Subscriber} "considers"
+ * since rule §2.3 forbids interaction from within the {@code onError} and {@code onComplete} methods.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.4'>2.4</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>It would be possible to check if there was an async interaction with the test's {@code Subscription}
+ * within a grace period but such check is still not generally decisive.</li>
+ * </ul>
+ */
+ void untested_spec204_blackbox_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception;
+ /**
+ * Asks for a {@code Subscriber}, signals {@code onSubscribe} twice synchronously and expects the second {@code Subscription} gets
+ * cancelled in a timely manner and without any calls to its {@code request} method.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.5'>2.5</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The test doesn't signal any other events than {@code onSubscribe} and may cause resource leak in
+ * {@code Subscriber}s that expect a finite {@code Publisher}.
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscribe.onSubscribe} implementation actually tries to detect multiple calls to it,</li>
+ * <li>if the second {@code Subscription} is cancelled asynchronously and that takes longer time than
+ * the {@code TestEnvironment}'s timeout permits.</li>
+ * </ul>
+ */
+ void required_spec205_blackbox_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Exception;
+
+ /**
+ * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation
+ * to make it cancel the {@code Subscription} for some external condition.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.6'>2.6</a>
+ */
+ void untested_spec206_blackbox_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception;
+ /**
+ * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation
+ * to issue requests based on external stimulus.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.7'>2.7</a>
+ */
+ void untested_spec207_blackbox_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception;
+ /**
+ * Currently, this test is skipped because there is no way to make the {@code Subscriber} implementation
+ * cancel the test's {@code Subscription} and check the outcome of sending {@code onNext}s after such
+ * cancel.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.8'>2.8</a>
+ */
+ void untested_spec208_blackbox_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable;
+ /**
+ * Asks for a {@code Subscriber}, expects it to request some amount and in turn be able to receive an {@code onComplete}
+ * synchronously from the {@code request} call without any {@code onNext} signals before that.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.9'>2.9</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The test ignores cancellation from the {@code Subscriber}.</li>
+ * <li>Invalid request amounts are ignored by this test.</li>
+ * <li>Concurrent calls to the test's {@code Subscription.request()} must be externally synchronized, otherwise
+ * such case results probabilistically in multiple {@code onComplete} calls by the test.</li>
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onComplete} methods.
+ * <li>if the {@code Subscriber} requires external stimulus to begin requesting; override the
+ * {@link SubscriberBlackboxVerification#triggerRequest(org.reactivestreams.Subscriber)} method
+ * in this case,</li>
+ * </ul>
+ */
+ void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable;
+ /**
+ * Asks for a {@code Subscriber} and expects it to handle {@code onComplete} independent of whether the {@code Subscriber}
+ * requests items or not.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.9'>2.9</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>Currently, the test doesn't call {@code onSubscribe} on the {@code Subscriber} which violates §1.9.
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onComplete} methods.
+ * </ul>
+ */
+ void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable;
+ /**
+ * Asks for a {@code Subscriber}, signals {@code onSubscribe} followed by an {@code onError} synchronously.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.10'>2.10</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>Despite the method name, the test doesn't expect a request signal from {@code Subscriber} and emits the
+ * {@code onError} signal anyway.
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onError} methods.
+ * </ul>
+ */
+ void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable;
+
+ /**
+ * Asks for a {@code Subscriber}, signals {@code onSubscribe} followed by an {@code onError} synchronously.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.10'>2.10</a>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or
+ * {@code onError} methods.
+ * </ul>
+ */
+ void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable;
+
+ /**
+ * Currently, this test is skipped because it would require analyzing what the {@code Subscriber} implementation
+ * does.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.11'>2.11</a>
+ */
+ void untested_spec211_blackbox_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception;
+ /**
+ * Currently, this test is skipped because the test for
+ * {@link #required_spec205_blackbox_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal §2.5}
+ * is in a better position to test for handling the reuse of the same {@code Subscriber}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.12'>2.12</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>In addition to §2.5, this rule could be better verified when testing a {@code Publisher}'s subscription behavior.
+ * </ul>
+ */
+ void untested_spec212_blackbox_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality() throws Throwable;
+ /**
+ * Currently, this test is skipped because it would require more control over the {@code Subscriber} to
+ * fail internally in response to a set of legal event emissions, not throw any exception from the {@code Subscriber}
+ * methods and have it cancel the {@code Subscription}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.13'>2.13</a>
+ */
+ void untested_spec213_blackbox_failingOnSignalInvocation() throws Exception;
+ /**
+ * Asks for a {@code Subscriber} and signals an {@code onSubscribe} event with {@code null} as a parameter and
+ * expects an immediate {@code NullPointerException} to be thrown by the {@code Subscriber.onSubscribe} method.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.13'>2.13</a>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws a {@code NullPointerException} from its {@code onSubscribe} method
+ * in response to a {@code null} parameter and not some other unchecked exception or no exception at all.
+ * </ul>
+ */
+ void required_spec213_blackbox_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable;
+ /**
+ * Asks for a {@code Subscriber}, signals an {@code onSubscribe} event followed by a
+ * {@code onNext} with {@code null} as a parameter and
+ * expects an immediate {@code NullPointerException} to be thrown by the {@code Subscriber.onNext} method.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.13'>2.13</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The test ignores cancellation and requests from the {@code Subscriber} and emits the {@code onNext}
+ * signal with a {@code null} parameter anyway.</li>
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws a {@code NullPointerException} from its {@code onNext} method
+ * in response to a {@code null} parameter and not some other unchecked exception or no exception at all.
+ * </ul>
+ */
+ void required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable;
+ /**
+ * Asks for a {@code Subscriber}, signals an {@code onSubscribe} event followed by a
+ * {@code onError} with {@code null} as a parameter and
+ * expects an immediate {@code NullPointerException} to be thrown by the {@code Subscriber.onError} method.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#2.13'>2.13</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The test ignores cancellation from the {@code Subscriber} and emits the {@code onError}
+ * signal with a {@code null} parameter anyway.</li>
+ * </ul>
+ * <p>
+ * If this test fails, the following could be checked within the {@code Subscriber} implementation:
+ * <ul>
+ * <li>if the {@code Subscriber} throws a {@code NullPointerException} from its {@code onNext} method
+ * in response to a {@code null} parameter and not some other unchecked exception or no exception at all.
+ * </ul>
+ */
+ void required_spec213_blackbox_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable;
+ /**
+ * Currently, this test is skipped because there is no agreed upon way for specifying, enforcing and testing
+ * a {@code Subscriber} with an arbitrary context.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.1'>3.1</a>
+ */
+ void untested_spec301_blackbox_mustNotBeCalledOutsideSubscriberContext() throws Exception;
+ /**
+ * Currently, this test is skipped because element production is the responsibility of the {@code Publisher} and
+ * a {@code Subscription} is not expected to be the active element in an established subscription.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.8'>3.8</a>
+ */
+ void untested_spec308_blackbox_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable;
+ /**
+ * Currently, this test is skipped because element production is the responsibility of the {@code Publisher} and
+ * a {@code Subscription} is not expected to be the active element in an established subscription.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.10'>3.10</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>This could be tested with a synchronous source currently not available within the TCK.</li>
+ * </ul>
+ */
+ void untested_spec310_blackbox_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception;
+ /**
+ * Currently, this test is skipped because signal production is the responsibility of the {@code Publisher} and
+ * a {@code Subscription} is not expected to be the active element in an established subscription.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.11'>3.11</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>Tests {@link #required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() §2.9}
+ * and {@link #required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() §2.10} are
+ * supposed to cover this case from the {@code Subscriber's} perspective.</li>
+ * </ul>
+ */
+ void untested_spec311_blackbox_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception;
+ /**
+ * Currently, this test is skipped because it is the responsibility of the {@code Publisher} deal with the case
+ * that all subscribers have cancelled their subscription.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.14'>3.14</a>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The specification lists this as an optional behavior because only some {@code Publisher} implementations
+ * (most likely {@code Processor}s) would coordinate with multiple {@code Subscriber}s.</li>
+ * </ul>
+ */
+ void untested_spec314_blackbox_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception;
+ /**
+ * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation
+ * thus there is no way to detect that the {@code Subscriber} called its own {@code onError} method in response
+ * to an exception thrown from {@code Subscription.cancel}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.15'>3.15</a>
+ */
+ void untested_spec315_blackbox_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception;
+ /**
+ * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation
+ * thus there is no way to detect that the {@code Subscriber} called its own {@code onError} method in response
+ * to an exception thrown from {@code Subscription.request}.
+ * <p>
+ * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.16'>3.16</a>
+ */
+ void untested_spec316_blackbox_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBufferOverflowException.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+public final class SubscriberBufferOverflowException extends RuntimeException {
+ public SubscriberBufferOverflowException() {
+ }
+
+ public SubscriberBufferOverflowException(String message) {
+ super(message);
+ }
+
+ public SubscriberBufferOverflowException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SubscriberBufferOverflowException(Throwable cause) {
+ super(cause);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberWhiteboxVerificationRules.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+/**
+ * Internal TCK use only.
+ * Add / Remove tests for PublisherVerificaSubscriberWhiteboxVerification here to make sure that they arre added/removed in the other places.
+ */
+public interface SubscriberWhiteboxVerificationRules {
+ void required_exerciseWhiteboxHappyPath() throws Throwable;
+ void required_spec201_mustSignalDemandViaSubscriptionRequest() throws Throwable;
+ void untested_spec202_shouldAsynchronouslyDispatch() throws Exception;
+ void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable;
+ void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable;
+ void untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception;
+ void required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Throwable;
+ void untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception;
+ void untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception;
+ void required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable;
+ void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable;
+ void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable;
+ void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable;
+ void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable;
+ void untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception;
+ void untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation() throws Throwable;
+ void untested_spec213_failingOnSignalInvocation() throws Exception;
+ void required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable;
+ void required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable;
+ void required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable;
+ void untested_spec301_mustNotBeCalledOutsideSubscriberContext() throws Exception;
+ void required_spec308_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable;
+ void untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception;
+ void untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception;
+ void untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception;
+ void untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception;
+ void untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/TestException.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.reactivestreams.tck.flow.support;
+
+/**
+ * Exception used by the TCK to signal failures.
+ * May be thrown or signalled through {@link org.reactivestreams.Subscriber#onError(Throwable)}.
+ */
+public final class TestException extends RuntimeException {
+ public TestException() {
+ super("Test Exception: Boom!");
+ }
+}
--- a/test/jdk/java/net/ipv6tests/B6521014.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/net/ipv6tests/B6521014.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,7 @@
}
static void test1(Inet6Address sin) throws Exception {
- try (ServerSocket ssock = new ServerSocket(0);
+ try (ServerSocket ssock = createBoundServer(sin);
Socket sock = new Socket()) {
int port = ssock.getLocalPort();
sock.connect(new InetSocketAddress(sin, port), 100);
@@ -82,7 +82,7 @@
}
static void test2(Inet6Address sin) throws Exception {
- try (ServerSocket ssock = new ServerSocket(0);
+ try (ServerSocket ssock = createBoundServer(sin);
Socket sock = new Socket()) {
int port = ssock.getLocalPort();
ssock.setSoTimeout(100);
@@ -94,6 +94,13 @@
}
}
+ static ServerSocket createBoundServer(Inet6Address sin) throws IOException {
+ ServerSocket ss = new ServerSocket();
+ InetSocketAddress address = new InetSocketAddress(sin, 0);
+ ss.bind(address);
+ return ss;
+ }
+
public static void main(String[] args) throws Exception {
Optional<Inet6Address> oaddr = getLocalAddr();
if (!oaddr.isPresent()) {
--- a/test/jdk/java/nio/channels/FileChannel/MapTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/nio/channels/FileChannel/MapTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -24,7 +24,7 @@
/* @test
* @bug 4429043 8002180
* @summary Test file mapping with FileChannel
- * @run main/othervm MapTest
+ * @run main/othervm/timeout=240 MapTest
* @key randomness
*/
@@ -195,7 +195,7 @@
* the data exercising various valid and invalid writeback ranges.
*/
private static void testForce() throws Exception {
- for (int x=0; x<100; x++) {
+ for (int x=0; x<50; x++) {
try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
FileChannel fc = raf.getChannel();
final int BLOCK_SIZE = 64;
--- a/test/jdk/java/nio/file/Files/Misc.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/nio/file/Files/Misc.java Mon Jul 22 11:08:27 2019 +0530
@@ -22,11 +22,14 @@
*/
/* @test
- * @bug 4313887 6838333 8005566 8032220 8215467
+ * @bug 4313887 6838333 8005566 8032220 8215467 8227080
* @summary Unit test for miscellenous methods in java.nio.file.Files
* @library ..
*/
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.channels.ClosedChannelException;
import java.nio.file.*;
import static java.nio.file.Files.*;
import static java.nio.file.LinkOption.*;
@@ -44,6 +47,7 @@
testIsSameFile(dir);
testFileTypeMethods(dir);
testAccessMethods(dir);
+ testSkip(dir);
} finally {
TestUtil.removeAll(dir);
}
@@ -372,6 +376,38 @@
}
}
+ /**
+ * Tests Files.newInputStream(Path).skip().
+ */
+ static void testSkip(Path tmpdir) throws IOException {
+ Path file = createFile(tmpdir.resolve("foo"));
+ try (OutputStream out = Files.newOutputStream(file)) {
+ byte[] blah = new byte[8192];
+ Arrays.fill(blah, (byte)42);
+ out.write(blah);
+ out.close();
+ try (InputStream in = Files.newInputStream(file)) {
+ assertTrue(in.skip(-1) == 0);
+ assertTrue(in.skip(0) == 0);
+ assertTrue(in.skip(blah.length/4) == blah.length/4);
+ assertTrue(in.skip(blah.length/2) == blah.length/2);
+ assertTrue(in.skip(Long.MAX_VALUE) == blah.length/4);
+ in.close();
+ try {
+ long n = in.skip(1);
+ throw new RuntimeException("skip() did not fail");
+ } catch (IOException ioe) {
+ if (!(ioe.getCause() instanceof ClosedChannelException)) {
+ throw new RuntimeException
+ ("IOException not caused by ClosedChannelException");
+ }
+ }
+ }
+ } finally {
+ delete(file);
+ }
+ }
+
static void assertTrue(boolean okay) {
if (!okay)
throw new RuntimeException("Assertion Failed");
--- a/test/jdk/java/sql/testng/util/TestPolicy.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/sql/testng/util/TestPolicy.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
* JDBC concrete classes
*/
public class TestPolicy extends Policy {
+ static final Policy DEFAULT_POLICY = Policy.getPolicy();
final PermissionCollection permissions = new Permissions();
@@ -137,6 +138,6 @@
@Override
public boolean implies(ProtectionDomain domain, Permission perm) {
- return permissions.implies(perm);
+ return permissions.implies(perm) || DEFAULT_POLICY.implies(domain, perm);
}
}
--- a/test/jdk/java/util/Calendar/SupplementalJapaneseEraTestRun.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/Calendar/SupplementalJapaneseEraTestRun.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -93,7 +93,9 @@
private static void testRun(String property, List<String> javaParam)
throws Throwable{
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-cp")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
+ .addToolArg("-cp")
.addToolArg(Utils.TEST_CLASS_PATH)
.addToolArg("-Djdk.calendar.japanese.supplemental.era=" + property)
.addToolArg("SupplementalJapaneseEraTest");
--- a/test/jdk/java/util/EnumSet/BogusEnumSet.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/EnumSet/BogusEnumSet.java Mon Jul 22 11:08:27 2019 +0530
@@ -32,11 +32,11 @@
public class BogusEnumSet {
public static void main(String[] args) throws Throwable {
- // This test depends on the current serialVersionUID of EnumSet,
- // which may change if the EnumSet class is modified.
- // The current value is -2409567991088730183L = 0xde8f7eadb5012fb9L
- // If the value changes, it will have to be patched into the
- // serialized byte stream below at the location noted.
+ // This test tries to deserialize a bogus stream produced with
+ // hypothetical EnumSet without a writeReplace() method - i.e.
+ // not using serialization proxy pattern. It tests that such
+ // stream is not accepted as valid stream - the EnumSet class
+ // declares a readObject() method which throws exception.
byte[] serializedForm = {
(byte)0xac, (byte)0xed, 0x0, 0x5, 0x73, 0x72, 0x0, 0x18,
0x6a, 0x61, 0x76, 0x61, 0x2e, 0x75, 0x74, 0x69,
@@ -45,10 +45,9 @@
0x7e, (byte)0xb0, (byte)0xd0, 0x7e, 0x2, 0x0, 0x1, 0x4a, 0x0, 0x8,
0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x78, 0x72, 0x0,
0x11, 0x6a, 0x61, 0x76, 0x61, 0x2e, 0x75, 0x74, 0x69,
- 0x6c, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x65, 0x74,
- // EnumSet's serialVersionUID is the following eight bytes (big-endian)
- (byte)0xde, (byte)0x8f, 0x7e, (byte)0xad, (byte)0xb5, (byte)0x01, 0x2f, (byte)0xb9,
- 0x2, 0x0, 0x2, 0x4c, 0x0, 0xb, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x6c, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x65, 0x74, 0xe,
+ 0x3, 0x21, 0x6a, (byte)0xcd, (byte)0x8c, 0x29, (byte)0xdd, 0x2,
+ 0x0, 0x2, 0x4c, 0x0, 0xb, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x54, 0x79, 0x70, 0x65, 0x74, 0x0, 0x11, 0x4c, 0x6a, 0x61, 0x76,
0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x43, 0x6c, 0x61, 0x73,
0x73, 0x3b, 0x5b, 0x0, 0x8, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/EnumSet/EnumSetClassSerialization.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8227368
+ * @summary Test deserialization of a stream containing EnumSet.class object
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.EnumSet;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class EnumSetClassSerialization {
+
+ public static void main(String[] args) throws Exception {
+ // EnumSet.class object serialized with JDK 8
+ int[] bytes = {
+ 0xac, 0xed, 0x00, 0x05, 0x76, 0x72, 0x00, 0x11, 0x6a, 0x61, 0x76, 0x61, 0x2e, 0x75, 0x74, 0x69,
+ 0x6c, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x65, 0x74, 0x0e, 0x03, 0x21, 0x6a, 0xcd, 0x8c, 0x29,
+ 0xdd, 0x02, 0x00, 0x02, 0x4c, 0x00, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79,
+ 0x70, 0x65, 0x74, 0x00, 0x11, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f,
+ 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3b, 0x5b, 0x00, 0x08, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73,
+ 0x65, 0x74, 0x00, 0x11, 0x5b, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f,
+ 0x45, 0x6e, 0x75, 0x6d, 0x3b, 0x78, 0x70
+ };
+
+ InputStream in = new InputStream() {
+ int i = 0;
+
+ @Override
+ public int read() {
+ return i < bytes.length ? bytes[i++] & 0xFF : -1;
+ }
+ };
+ ObjectInputStream ois = new ObjectInputStream(in);
+
+ Object res = ois.readObject();
+
+ if (res != EnumSet.class) {
+ throw new AssertionError(
+ "Expected: " + EnumSet.class + ", got: " + res);
+ }
+ }
+
+ /**
+ * This class can be used to print out lines that constitute
+ * the 'bytes' variable initializer in the test.
+ */
+ public static class Serializer {
+ public static void main(String[] args) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(EnumSet.class);
+ oos.close();
+ byte[] bytes = baos.toByteArray();
+ int bpl = 16;
+ System.out.print(
+ IntStream
+ .range(0, (bytes.length + bpl - 1) / bpl)
+ .mapToObj(i -> IntStream
+ .range(
+ i * bpl,
+ Math.min(i * bpl + bpl, bytes.length)
+ )
+ .mapToObj(ii -> {
+ String s = Integer.toHexString(bytes[ii] & 0xFF);
+ return s.length() == 1 ? "0x0" + s : "0x" + s;
+ })
+ .collect(Collectors.joining(", "))
+ )
+ .collect(Collectors.joining(",\n ", "int[] bytes = {\n ", "\n};"))
+ );
+ }
+ }
+}
--- a/test/jdk/java/util/Locale/SoftKeys.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/Locale/SoftKeys.java Mon Jul 22 11:08:27 2019 +0530
@@ -24,10 +24,10 @@
* @test
* @bug 8196869
* @summary Make sure we deal with internal Key data being cleared properly
- * @run main/othervm -Xms16m -Xmx16m -esa SoftKeys
* @ignore This test aims to provoke NPEs, but due to the need to constrain
* memory usage it fails intermittently with OOME on various systems
* with no way to ignore such failures.
+ * @run main/othervm -Xms16m -Xmx16m -esa SoftKeys
*/
import java.util.*;
--- a/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,8 @@
String cp = Utils.TEST_CLASSES + File.pathSeparator + Utils.TEST_SRC
+ File.pathSeparator + ".";
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-esa")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
.addToolArg("-cp")
.addToolArg(cp)
.addToolArg("MissingResourceCauseTest");
--- a/test/jdk/java/util/ResourceBundle/modules/ModuleTestUtil.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/ResourceBundle/modules/ModuleTestUtil.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,7 +134,9 @@
public static void runModule(String mp, String mn, List<String> localeList)
throws Throwable {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-p")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
+ .addToolArg("-p")
.addToolArg(mp)
.addToolArg("-m")
.addToolArg(mn);
@@ -160,7 +162,9 @@
public static void runModuleWithCp(String cp, String mp, String mn,
List<String> localeList, boolean expected) throws Throwable {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-cp")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
+ .addToolArg("-cp")
.addToolArg(cp)
.addToolArg("-p")
.addToolArg(mp)
--- a/test/jdk/java/util/ResourceBundle/modules/layer/LayerTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/ResourceBundle/modules/layer/LayerTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,9 @@
private static void runCmd() throws Throwable {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-cp")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
+ .addToolArg("-cp")
.addToolArg(Utils.TEST_CLASSES)
.addToolArg("Main")
.addToolArg(Utils.TEST_CLASSES);
--- a/test/jdk/java/util/ResourceBundle/modules/unnamed/UnNamedTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/ResourceBundle/modules/unnamed/UnNamedTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,9 @@
private static void runCmd() throws Throwable {
// access resource bundles that are exported private unconditionally.
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-cp")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
+ .addToolArg("-cp")
.addToolArg(Utils.TEST_CLASSES)
.addToolArg("--module-path")
.addToolArg(MODS_DIR.toString())
@@ -92,7 +94,9 @@
// --add-exports can't open resources
launcher = JDKToolLauncher.createUsingTestJDK("java");
- launcher.addToolArg("-cp")
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa")
+ .addToolArg("-cp")
.addToolArg(Utils.TEST_CLASSES)
.addToolArg("--module-path")
.addToolArg(MODS_DIR.toString())
--- a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -329,6 +329,8 @@
private int runCmd(List<String> argsList) throws Throwable {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
+ launcher.addToolArg("-ea")
+ .addToolArg("-esa");
argsList.forEach(launcher::addToolArg);
return ProcessTools.executeCommand(launcher.getCommand()).getExitValue();
--- a/test/jdk/java/util/TimeZone/Bug8066652Run.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/TimeZone/Bug8066652Run.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,8 @@
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
//Setting invalid TimeZone using VM option
launcher.addToolArg("-Duser.timezone=Foo/Bar")
+ .addToolArg("-ea")
+ .addToolArg("-esa")
.addToolArg("-cp")
.addToolArg(cp)
.addToolArg("Bug8066652");
--- a/test/jdk/java/util/TimeZone/TimeZoneDatePermissionCheckRun.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/java/util/TimeZone/TimeZoneDatePermissionCheckRun.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,8 @@
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
launcher.addToolArg("-Djava.security.manager")
.addToolArg("-Djava.security.debug=access,failure,policy")
+ .addToolArg("-ea")
+ .addToolArg("-esa")
.addToolArg("-cp")
.addToolArg(jarPath)
.addToolArg("TimeZoneDatePermissionCheck");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/accessibility/JTable/JTableCellEditor.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Locale;
+
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleTable;
+import javax.swing.JFrame;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * @test
+ * @bug 8226653
+ * @key headful
+ * @summary The active cell editor should be reported as a child of the table.
+ * Note that the accessibility API ignores the real children of the
+ * table, but reports the "virtual" child per cell in the grid.
+ */
+public final class JTableCellEditor {
+
+ private static final int COUNT = 3;
+ private static JTable table;
+ private static JFrame frame;
+
+ public static void main(final String[] args)
+ throws InvocationTargetException, InterruptedException {
+ EventQueue.invokeAndWait(() -> {
+ frame = new JFrame();
+ table = new JTable(testSelectionWithFilterTable());
+ frame.add(table);
+ frame.pack();
+ });
+ EventQueue.invokeAndWait(() -> table.editCellAt(1, 1));
+ EventQueue.invokeAndWait(() -> {
+ AccessibleTable aTable = table.getAccessibleContext()
+ .getAccessibleTable();
+ int aColumns = aTable.getAccessibleColumnCount();
+ int aRows = aTable.getAccessibleRowCount();
+ // We cannot assume which component will be used as an editor of the
+ // table cell, but we can expect it will have the "text" role.
+ AccessibleRole role = aTable.getAccessibleAt(1, 1)
+ .getAccessibleContext()
+ .getAccessibleRole();
+ frame.dispose();
+ if (!role.toDisplayString(Locale.ENGLISH).equals("text")) {
+ throw new RuntimeException("Unexpected role: " + role);
+ }
+ if (aColumns != COUNT) {
+ throw new RuntimeException("Wrong columns: " + aColumns);
+ }
+ if (aRows != COUNT) {
+ throw new RuntimeException("Wrong rows: " + aRows);
+ }
+ });
+ }
+
+ /**
+ * Creates a dummy table model.
+ */
+ private static TableModel testSelectionWithFilterTable() {
+ DefaultTableModel model = new DefaultTableModel(0, 3);
+ for (int i = 0; i < COUNT; i++) {
+ model.addRow(new Object[]{i + "x0", i + "x1", i + "x2"});
+ }
+ return model;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8181386
+ * @summary CipherSpi ByteBuffer to byte array conversion fails for
+ * certain data overlap conditions
+ * @run main CipherByteBufferOverwriteTest 0 false
+ * @run main CipherByteBufferOverwriteTest 0 true
+ * @run main CipherByteBufferOverwriteTest 4 false
+ * @run main CipherByteBufferOverwriteTest 4 true
+ */
+
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class CipherByteBufferOverwriteTest {
+
+ private static final boolean DEBUG = false;
+
+ private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
+
+ // must be larger than the temp array size, i.e. 4096, hardcoded in
+ // javax.crypto.CipherSpi class
+ private static final int PLAINTEXT_SIZE = 8192;
+ // leave room for padding
+ private static final int CIPHERTEXT_BUFFER_SIZE = PLAINTEXT_SIZE + 32;
+
+ private static final SecretKey KEY = new SecretKeySpec(new byte[16], "AES");
+ private static final AlgorithmParameterSpec PARAMS =
+ new IvParameterSpec(new byte[16]);
+
+ private static ByteBuffer inBuf;
+ private static ByteBuffer outBuf;
+
+ private enum BufferType {
+ ALLOCATE, DIRECT, WRAP;
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ int offset = Integer.parseInt(args[0]);
+ boolean useRO = Boolean.parseBoolean(args[1]);
+
+ // an all-zeros plaintext is the easiest way to demonstrate the issue,
+ // but it fails with any plaintext, of course
+ byte[] expectedPT = new byte[PLAINTEXT_SIZE];
+ byte[] buf = new byte[offset + CIPHERTEXT_BUFFER_SIZE];
+ System.arraycopy(expectedPT, 0, buf, 0, PLAINTEXT_SIZE);
+
+ // generate expected cipher text using byte[] methods
+ Cipher c = Cipher.getInstance(TRANSFORMATION);
+ c.init(Cipher.ENCRYPT_MODE, KEY, PARAMS);
+ byte[] expectedCT = c.doFinal(expectedPT);
+
+ // Test#1: against ByteBuffer generated with allocate(int) call
+ prepareBuffers(BufferType.ALLOCATE, useRO, buf.length,
+ buf, 0, PLAINTEXT_SIZE, offset);
+
+ runTest(offset, expectedPT, expectedCT);
+ System.out.println("\tALLOCATE: passed");
+
+ // Test#2: against direct ByteBuffer
+ prepareBuffers(BufferType.DIRECT, useRO, buf.length,
+ buf, 0, PLAINTEXT_SIZE, offset);
+ System.out.println("\tDIRECT: passed");
+
+ runTest(offset, expectedPT, expectedCT);
+
+ // Test#3: against ByteBuffer wrapping existing array
+ prepareBuffers(BufferType.WRAP, useRO, buf.length,
+ buf, 0, PLAINTEXT_SIZE, offset);
+
+ runTest(offset, expectedPT, expectedCT);
+ System.out.println("\tWRAP: passed");
+
+ System.out.println("All Tests Passed");
+ }
+
+ private static void prepareBuffers(BufferType type,
+ boolean useRO, int bufSz, byte[] in, int inOfs, int inLen,
+ int outOfs) {
+ switch (type) {
+ case ALLOCATE:
+ outBuf = ByteBuffer.allocate(bufSz);
+ inBuf = outBuf.slice();
+ inBuf.put(in, inOfs, inLen);
+ inBuf.rewind();
+ inBuf.limit(inLen);
+ outBuf.position(outOfs);
+ break;
+ case DIRECT:
+ outBuf = ByteBuffer.allocateDirect(bufSz);
+ inBuf = outBuf.slice();
+ inBuf.put(in, inOfs, inLen);
+ inBuf.rewind();
+ inBuf.limit(inLen);
+ outBuf.position(outOfs);
+ break;
+ case WRAP:
+ if (in.length < bufSz) {
+ throw new RuntimeException("ERROR: Input buffer too small");
+ }
+ outBuf = ByteBuffer.wrap(in);
+ inBuf = ByteBuffer.wrap(in, inOfs, inLen);
+ outBuf.position(outOfs);
+ break;
+ }
+ if (useRO) {
+ inBuf = inBuf.asReadOnlyBuffer();
+ }
+ if (DEBUG) {
+ System.out.println("inBuf, pos = " + inBuf.position() +
+ ", capacity = " + inBuf.capacity() +
+ ", limit = " + inBuf.limit() +
+ ", remaining = " + inBuf.remaining());
+ System.out.println("outBuf, pos = " + outBuf.position() +
+ ", capacity = " + outBuf.capacity() +
+ ", limit = " + outBuf.limit() +
+ ", remaining = " + outBuf.remaining());
+ }
+ }
+
+ private static void runTest(int ofs, byte[] expectedPT, byte[] expectedCT)
+ throws Exception {
+
+ Cipher c = Cipher.getInstance(TRANSFORMATION);
+ c.init(Cipher.ENCRYPT_MODE, KEY, PARAMS);
+ int ciphertextSize = c.doFinal(inBuf, outBuf);
+
+ // read out the encrypted result
+ outBuf.position(ofs);
+ byte[] finalCT = new byte[ciphertextSize];
+ if (DEBUG) {
+ System.out.println("runTest, ciphertextSize = " + ciphertextSize);
+ System.out.println("runTest, ofs = " + ofs +
+ ", remaining = " + finalCT.length +
+ ", limit = " + outBuf.limit());
+ }
+ outBuf.get(finalCT);
+
+ if (!Arrays.equals(finalCT, expectedCT)) {
+ throw new Exception("ERROR: Ciphertext does not match");
+ }
+
+ // now do decryption
+ outBuf.position(ofs);
+ outBuf.limit(ofs + ciphertextSize);
+
+ c.init(Cipher.DECRYPT_MODE, KEY, PARAMS);
+ ByteBuffer finalPTBuf = ByteBuffer.allocate(
+ c.getOutputSize(outBuf.remaining()));
+ c.doFinal(outBuf, finalPTBuf);
+
+ // read out the decrypted result
+ finalPTBuf.flip();
+ byte[] finalPT = new byte[finalPTBuf.remaining()];
+ finalPTBuf.get(finalPT);
+
+ if (!Arrays.equals(finalPT, expectedPT)) {
+ throw new Exception("ERROR: Plaintext does not match");
+ }
+ }
+}
+
--- a/test/jdk/javax/net/ssl/SSLSession/SessionTimeOutTests.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/javax/net/ssl/SSLSession/SessionTimeOutTests.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -283,7 +283,7 @@
}
System.out.print(sess + " " + lifetime);
if (((timeout == 0) || (lifetime < timeout)) &&
- (isTimedout == "YES")) {
+ (isTimedout.equals("YES"))) {
isTimedout = "Invalidated before timeout";
}
--- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Mon Jul 22 11:08:27 2019 +0530
@@ -100,6 +100,7 @@
"CMRefRoots",
"WaitForStrongCLD",
"WeakCLDRoots",
+ "MergeER",
"MergeHCC",
"MergeRS",
"MergeLB",
--- a/test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -264,7 +264,6 @@
Recording recording = new Recording();
- recording.enable(EventNames.BiasedLockRevocation);
recording.enable(EventNames.BiasedLockClassRevocation);
recording.enable(EventNames.ExecuteVMOperation);
recording.start();
@@ -274,8 +273,7 @@
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
- // Determine which safepoints included single and bulk revocation VM operations
- Set<Long> vmOperationsSingle = new HashSet<>();
+ // Determine which safepoints included bulk revocation VM operations
Set<Long> vmOperationsBulk = new HashSet<>();
for (RecordedEvent event : events) {
@@ -283,27 +281,17 @@
String operation = event.getValue("operation");
Long safepointId = event.getValue("safepointId");
- if (operation.equals("RevokeBias")) {
- vmOperationsSingle.add(safepointId);
- } else if (operation.equals("BulkRevokeBias")) {
+ if (operation.equals("BulkRevokeBias")) {
vmOperationsBulk.add(safepointId);
}
}
}
- int revokeCount = 0;
int bulkRevokeCount = 0;
// Match all revoke events to a corresponding VMOperation event
for (RecordedEvent event : events) {
- if (event.getEventType().getName().equals(EventNames.BiasedLockRevocation)) {
- Long safepointId = event.getValue("safepointId");
- String lockClass = ((RecordedClass)event.getValue("lockClass")).getName();
- if (lockClass.equals(MyLock.class.getName())) {
- Asserts.assertTrue(vmOperationsSingle.contains(safepointId));
- revokeCount++;
- }
- } else if (event.getEventType().getName().equals(EventNames.BiasedLockClassRevocation)) {
+ if (event.getEventType().getName().equals(EventNames.BiasedLockClassRevocation)) {
Long safepointId = event.getValue("safepointId");
String lockClass = ((RecordedClass)event.getValue("revokedClass")).getName();
if (lockClass.toString().equals(MyLock.class.getName())) {
@@ -314,6 +302,5 @@
}
Asserts.assertGT(bulkRevokeCount, 0);
- Asserts.assertGT(revokeCount, bulkRevokeCount);
}
}
Binary file test/jdk/sun/misc/ClassLoaderUtil/test.jar has changed
--- a/test/jdk/sun/net/www/protocol/file/DirPermissionDenied.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/file/DirPermissionDenied.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,8 +90,12 @@
}
@AfterTest
- public void tearDown() throws IOException {
+ public void tearDown() throws Throwable {
+ // add read permission to ensure the dir removable
+ ProcessTools.executeCommand("chmod", "733", TEST_DIR.toString())
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .shouldHaveExitValue(0);
FileUtils.deleteFileIfExistsWithRetry(TEST_DIR);
}
}
-
--- a/test/jdk/sun/net/www/protocol/http/NoCache.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/NoCache.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,9 +25,11 @@
* @test
* @bug 7133367
* @modules jdk.httpserver
+ * @library /test/lib
* @summary ResponseCache.put should not be called when setUseCaches(false)
*/
+
import java.net.*;
import java.io.IOException;
import java.util.List;
@@ -35,6 +37,7 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
+import jdk.test.lib.net.URIBuilder;
public class NoCache
{
@@ -43,9 +46,13 @@
HttpServer server = startHttpServer();
try {
- URL url = new URL("http://" + InetAddress.getLocalHost().getHostAddress()
- + ":" + server.getAddress().getPort() + "/NoCache/");
- URLConnection uc = url.openConnection();
+ URL url = URIBuilder.newBuilder()
+ .scheme("http")
+ .host(server.getAddress().getAddress())
+ .port(server.getAddress().getPort())
+ .path("/NoCache/")
+ .toURLUnchecked();
+ URLConnection uc = url.openConnection(Proxy.NO_PROXY);
uc.setUseCaches(false);
uc.getInputStream().close();
} finally {
@@ -70,7 +77,7 @@
// HTTP Server
static HttpServer startHttpServer() throws IOException {
- HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ HttpServer httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 0), 0);
httpServer.createContext("/NoCache/", new SimpleHandler());
httpServer.start();
return httpServer;
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @bug 6614957
* @summary HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
* @modules jdk.httpserver
+ * @library /test/lib
* @run main/othervm HttpsSocketFacTest
*
* SunJSSE does not support dynamic system properties, no way to re-use
@@ -38,11 +39,12 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
-import java.security.NoSuchAlgorithmException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
+import java.net.Proxy;
+import java.security.NoSuchAlgorithmException;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.IOException;
@@ -50,6 +52,7 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpsConfigurator;
+import jdk.test.lib.net.URIBuilder;
/*
* This class tests that the HTTPS protocol handler is using its socket factory for
@@ -103,10 +106,15 @@
void doClient() throws IOException {
InetSocketAddress address = httpsServer.getAddress();
- URL url = new URL("https://localhost:" + address.getPort() + "/test6614957/");
+ URL url = URIBuilder.newBuilder()
+ .scheme("https")
+ .loopback()
+ .port(address.getPort())
+ .path("/test6614957/")
+ .toURLUnchecked();
System.out.println("trying to connect to " + url + "...");
- HttpsURLConnection uc = (HttpsURLConnection) url.openConnection();
+ HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(Proxy.NO_PROXY);
SimpleSSLSocketFactory sssf = new SimpleSSLSocketFactory();
uc.setSSLSocketFactory(sssf);
uc.setHostnameVerifier(new AllHostnameVerifier());
@@ -129,7 +137,8 @@
* Https Server
*/
public void startHttpsServer() throws IOException, NoSuchAlgorithmException {
- httpsServer = com.sun.net.httpserver.HttpsServer.create(new InetSocketAddress(0), 0);
+ httpsServer = com.sun.net.httpserver.HttpsServer
+ .create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
httpsServer.createContext("/test6614957/", new MyHandler());
httpsServer.setHttpsConfigurator(new HttpsConfigurator(SSLContext.getDefault()));
httpsServer.start();
--- a/test/jdk/sun/security/krb5/auto/KDC.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/security/krb5/auto/KDC.java Mon Jul 22 11:08:27 2019 +0530
@@ -1274,7 +1274,17 @@
PAData[] inPAs = KDCReqDotPAData(asReq);
List<PAData> enc_outPAs = new ArrayList<>();
- if (inPAs == null || inPAs.length == 0) {
+
+ byte[] paEncTimestamp = null;
+ if (inPAs != null) {
+ for (PAData inPA : inPAs) {
+ if (inPA.getType() == Krb5.PA_ENC_TIMESTAMP) {
+ paEncTimestamp = inPA.getValue();
+ }
+ }
+ }
+
+ if (paEncTimestamp == null) {
Object preauth = options.get(Option.PREAUTH_REQUIRED);
if (preauth == null || preauth.equals(Boolean.TRUE)) {
throw new KrbException(Krb5.KDC_ERR_PREAUTH_REQUIRED);
@@ -1283,7 +1293,7 @@
EncryptionKey pakey = null;
try {
EncryptedData data = newEncryptedData(
- new DerValue(inPAs[0].getValue()));
+ new DerValue(paEncTimestamp));
pakey = keyForUser(body.cname, data.getEType(), false);
data.decrypt(pakey, KeyUsage.KU_PA_ENC_TS);
} catch (Exception e) {
--- a/test/jdk/sun/security/tools/keytool/DefaultSignatureAlgorithm.java Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * 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 8138766
- * @key intermittent
- * @summary New default -sigalg for keytool
- * @modules java.base/sun.security.tools.keytool
- * @modules jdk.crypto.ec
- * @run main/othervm DefaultSignatureAlgorithm RSA 1024 SHA256withRSA
- * @run main/othervm DefaultSignatureAlgorithm RSA 3072 SHA256withRSA
- * @run main/othervm DefaultSignatureAlgorithm RSA 3073 SHA384withRSA
- * @run main/othervm DefaultSignatureAlgorithm DSA 1024 SHA256withDSA
- * @run main/othervm/timeout=700 DefaultSignatureAlgorithm DSA 3072
- * SHA256withDSA
- * @run main/othervm DefaultSignatureAlgorithm EC 192 SHA256withECDSA
- * @run main/othervm DefaultSignatureAlgorithm EC 384 SHA384withECDSA
- * @run main/othervm DefaultSignatureAlgorithm EC 571 SHA512withECDSA
- * @run main/othervm DefaultSignatureAlgorithm EC 571 SHA256withECDSA
- * SHA256withECDSA
- */
-
-import sun.security.tools.keytool.Main;
-
-import java.io.File;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
-
-public class DefaultSignatureAlgorithm {
-
- public static void main(String[] args) throws Exception {
- if(args == null || args.length < 3) {
- throw new RuntimeException("Invalid arguments provided.");
- }
- String sigAlg = (args.length == 4) ? args[3] : null;
- run(args[0], Integer.valueOf(args[1]), args[2], sigAlg);
- }
-
- private static void run(String keyAlg, int keySize,
- String expectedSigAlg, String sigAlg) throws Exception {
- String alias = keyAlg + keySize + System.currentTimeMillis();
- String cmd = "-keystore ks -storepass changeit" +
- " -keypass changeit -alias " + alias +
- " -keyalg " + keyAlg + " -keysize " + keySize +
- " -genkeypair -dname CN=" + alias + " -debug";
- if (sigAlg != null) {
- cmd += " -sigalg " + sigAlg;
- }
- Main.main(cmd.split(" "));
-
- KeyStore ks = KeyStore.getInstance(
- new File("ks"), "changeit".toCharArray());
- X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
- String actualSigAlg = cert.getSigAlgName();
- if (!actualSigAlg.equals(expectedSigAlg)) {
- throw new Exception("Failure at " + alias + ": expected "
- + expectedSigAlg + ", actually " + actualSigAlg);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/fakegen/DefaultSignatureAlgorithm.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8138766 8227059
+ * @summary New default -sigalg for keytool
+ * @library /test/lib
+ * @build java.base/sun.security.rsa.RSAKeyPairGenerator
+ * java.base/sun.security.provider.DSAKeyPairGenerator
+ * jdk.crypto.ec/sun.security.ec.ECKeyPairGenerator
+ * @run main DefaultSignatureAlgorithm
+ * @modules jdk.crypto.ec
+ */
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+import java.io.File;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+
+public class DefaultSignatureAlgorithm {
+
+ static int pos = 0;
+
+ public static void main(String[] args) throws Exception {
+ check("RSA", 1024, null, "SHA256withRSA");
+ check("RSA", 3072, null, "SHA256withRSA");
+ check("RSA", 3073, null, "SHA384withRSA");
+ check("RSA", 7680, null, "SHA384withRSA");
+ check("RSA", 7681, null, "SHA512withRSA");
+
+ check("DSA", 1024, null, "SHA256withDSA");
+ check("DSA", 3072, null, "SHA256withDSA");
+
+ check("EC", 192, null, "SHA256withECDSA");
+ check("EC", 384, null, "SHA384withECDSA");
+ check("EC", 571, null, "SHA512withECDSA");
+
+ check("EC", 571, "SHA256withECDSA", "SHA256withECDSA");
+ }
+
+ private static void check(String keyAlg, int keySize,
+ String requestedSigAlg, String expectedSigAlg)
+ throws Exception {
+ String alias = keyAlg + keySize + "-" + pos++;
+ String sigAlgParam = requestedSigAlg == null
+ ? ""
+ : (" -sigalg " + requestedSigAlg);
+ genkeypair(alias,
+ "-keyalg " + keyAlg + " -keysize " + keySize + sigAlgParam)
+ .shouldHaveExitValue(0);
+
+ KeyStore ks = KeyStore.getInstance(
+ new File("ks"), "changeit".toCharArray());
+ X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
+ Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), keyAlg);
+ Asserts.assertEQ(cert.getSigAlgName(), expectedSigAlg);
+ }
+
+ static OutputAnalyzer genkeypair(String alias, String options)
+ throws Exception {
+ String patchArg = "-J--patch-module=java.base="
+ + System.getProperty("test.classes")
+ + File.separator + "patches" + File.separator + "java.base"
+ + " -J--patch-module=jdk.crypto.ec="
+ + System.getProperty("test.classes")
+ + File.separator + "patches" + File.separator + "jdk.crypto.ec";;
+ return kt(patchArg + " -genkeypair -alias " + alias
+ + " -dname CN=" + alias + " " + options);
+ }
+
+ static OutputAnalyzer kt(String cmd)
+ throws Exception {
+ return SecurityTools.keytool("-storepass changeit -keypass changeit "
+ + "-keystore ks " + cmd);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/fakegen/PSS.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8215694 8222987 8225257
+ * @summary keytool cannot generate RSASSA-PSS certificates
+ * @library /test/lib
+ * @build java.base/sun.security.rsa.RSAKeyPairGenerator
+ * @modules java.base/sun.security.util
+ * java.base/sun.security.x509
+ * @requires os.family != "solaris"
+ * @run main PSS
+ */
+
+// This test is excluded from Solaris because the 8192-bit RSA key pair
+// generator is extremely slow there.
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.security.DerUtils;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
+
+import java.io.File;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+
+public class PSS {
+
+ public static void main(String[] args) throws Exception {
+
+ genkeypair("p", "-keyalg RSASSA-PSS -sigalg RSASSA-PSS")
+ .shouldHaveExitValue(0);
+
+ genkeypair("a", "-keyalg RSA -sigalg RSASSA-PSS -keysize 2048")
+ .shouldHaveExitValue(0);
+
+ genkeypair("b", "-keyalg RSA -sigalg RSASSA-PSS -keysize 4096")
+ .shouldHaveExitValue(0);
+
+ genkeypair("c", "-keyalg RSA -sigalg RSASSA-PSS -keysize 8192")
+ .shouldHaveExitValue(0);
+
+ KeyStore ks = KeyStore.getInstance(
+ new File("ks"), "changeit".toCharArray());
+
+ check((X509Certificate)ks.getCertificate("p"), "RSASSA-PSS",
+ AlgorithmId.SHA256_oid);
+
+ check((X509Certificate)ks.getCertificate("a"), "RSA",
+ AlgorithmId.SHA256_oid);
+
+ check((X509Certificate)ks.getCertificate("b"), "RSA",
+ AlgorithmId.SHA384_oid);
+
+ check((X509Certificate)ks.getCertificate("c"), "RSA",
+ AlgorithmId.SHA512_oid);
+
+ // More commands
+ kt("-certreq -alias p -sigalg RSASSA-PSS -file p.req")
+ .shouldHaveExitValue(0);
+
+ kt("-gencert -alias a -sigalg RSASSA-PSS -infile p.req -outfile p.cert")
+ .shouldHaveExitValue(0);
+
+ kt("-importcert -alias p -file p.cert")
+ .shouldHaveExitValue(0);
+
+ kt("-selfcert -alias p -sigalg RSASSA-PSS")
+ .shouldHaveExitValue(0);
+ }
+
+ static OutputAnalyzer genkeypair(String alias, String options)
+ throws Exception {
+ String patchArg = "-J--patch-module=java.base=" + System.getProperty("test.classes")
+ + File.separator + "patches" + File.separator + "java.base";
+ return kt(patchArg + " -genkeypair -alias " + alias
+ + " -dname CN=" + alias + " " + options);
+ }
+
+ static OutputAnalyzer kt(String cmd)
+ throws Exception {
+ return SecurityTools.keytool("-storepass changeit -keypass changeit "
+ + "-keystore ks " + cmd);
+ }
+
+ static void check(X509Certificate cert, String expectedKeyAlg,
+ ObjectIdentifier expectedMdAlg) throws Exception {
+ Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), expectedKeyAlg);
+ Asserts.assertEQ(cert.getSigAlgName(), "RSASSA-PSS");
+ DerUtils.checkAlg(cert.getSigAlgParams(), "000", expectedMdAlg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/provider/DSAKeyPairGenerator.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * A fake DSA key pair generator
+ */
+class DSAKeyPairGenerator extends KeyPairGenerator {
+
+ private int plen;
+
+ DSAKeyPairGenerator(int defaultKeySize) {
+ super("DSA");
+ this.plen = defaultKeySize;
+ }
+
+ public void initialize(int modlen, SecureRandom random) {
+ this.plen = modlen;
+ }
+
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random) {
+ throw new UnsupportedOperationException();
+ }
+
+ public KeyPair generateKeyPair() {
+ BigInteger p, q, g, x, y;
+ switch (plen) {
+ case 1024:
+ p = new BigInteger("178011905478542266528237562450159990145232"
+ + "156369120674273274450314442865788737020770612695252"
+ + "123463079567156784778466449970650770920727857050009"
+ + "668388144034129745221171818506047231150039301079959"
+ + "358067395348717066319802262019714966524135060945913"
+ + "707594956514672855690606794135837542707371727429551"
+ + "343320695239");
+ q = new BigInteger("864205495604807476120572616017955259175325"
+ + "408501");
+ g = new BigInteger("174068207532402095185811980123523436538604"
+ + "490794561350978495831040599953488455823147851597408"
+ + "940950725307797094915759492368300574252438761037084"
+ + "473467180148876118103083043754985190983472601550494"
+ + "691329488083395492313850000361646482644608492304078"
+ + "721818959999056496097769368017749273708962006689187"
+ + "956744210730");
+ x = new BigInteger("442684721233431748836258763370873041965448"
+ + "305045");
+ y = new BigInteger("123777377875361061959303516913138943002334"
+ + "907914087825062123737715425120688699041350157178201"
+ + "400875613890444051801751930684745642628053940339973"
+ + "838660880918443284038995141330502246221730915504106"
+ + "313025753680709037893119973285385498869618080832350"
+ + "844717549458284541384384444940685082987448444197127"
+ + "109727215326");
+ break;
+ case 3072:
+ p = new BigInteger("532424770282957507167558442446475365039221"
+ + "865310725601984444684810811113744209961033785957055"
+ + "545569814329215072178264469737927701168579964248618"
+ + "212671015750272795670312875451455848633455356647610"
+ + "802537682630581977793580392148938495801039643027210"
+ + "168055234243089546290868853109011307872303192870862"
+ + "928522910714047973751079687063489704904165319118754"
+ + "414656318529199596549052269402875554159175957058778"
+ + "440558421673575502884909440510567191072050738584727"
+ + "120524174557883883057055053123583287619621138916493"
+ + "103747092870334536468061850120264153241617645557971"
+ + "369719361654590867807897284715299844320510777830158"
+ + "726099043158186232574541934847234927190558272654504"
+ + "899757279197741136733127726856995584055651857157703"
+ + "730144527174175430693903863066052387871964460507889"
+ + "647358151911550149297202134918108185581732063173116"
+ + "923323722454275514471399056679497166381315291238166"
+ + "678637058042047687405023560967657729197010282296512"
+ + "1019243318222397");
+ q = new BigInteger("890750162030504407723769200757822201430799"
+ + "34855896740921457815099167207156753");
+ g = new BigInteger("151817606774376623890824510431247991418389"
+ + "715779225250508738780526725946562383344295250350988"
+ + "771843988677909140611473778208677098146023000408394"
+ + "159085130929460916510001933636711147155614261913281"
+ + "024881629605746742555704817858764668833915862917006"
+ + "598838541275997577579609978297421111961935816027196"
+ + "483840098753346970227821715342000582711792748060856"
+ + "726896896804543780217869880654497603605897208724113"
+ + "159746510357451233393865294043543249227656881945445"
+ + "911394836487973565655780621125471620102365417701222"
+ + "942700788591992318925980959657031578942777920589286"
+ + "616050851348109471636081284309144953091734152913609"
+ + "446411782660994503265873790796828974300693496175976"
+ + "687169380996928285288177682058646187108156643041984"
+ + "849723272840833108573298006600021948389582796433112"
+ + "947515654733901137745000270350091408182905439114222"
+ + "789179830877253611946986888461931792357280552721443"
+ + "254779196196933589018709692301251250169609249601817"
+ + "4795480503442737");
+ x = new BigInteger("837184725379267020693579006510066460977336"
+ + "11851797067505263114214549968402803");
+ y = new BigInteger("395340495486576955293430186860596538887519"
+ + "532234445217156133155957480616804094258448364164620"
+ + "019669119585215430588435624960233328621409901309332"
+ + "192899527076171337665680476899693664056285881110265"
+ + "747619109873269836751712303602309960796986216520795"
+ + "801714761851172570535758859846766099312622783018124"
+ + "479033035974495130498276693342256396509951099944860"
+ + "886247767918456849069941054372775951688384599525157"
+ + "707186634084399395289878437457318095050730531728857"
+ + "772445883395712924633196197942869159234956079072812"
+ + "033713932103618702222793066673087288841096282175640"
+ + "243353943285718935517693389945339235110435667386410"
+ + "827568246083609394541667076709869892137539964277111"
+ + "881671381034966060604088870102183420000265271778711"
+ + "380501229707440889595235145225482336904915838699846"
+ + "941323450568220944649213026904670943083185766542427"
+ + "196471392765688014947830444837953042683779059773143"
+ + "877079141940001705246446188097009313372159366032655"
+ + "5436444354063312");
+ break;
+ default:
+ throw new AssertionError("Unknown keySize " + plen);
+ }
+
+ try {
+ return new KeyPair(new DSAPublicKeyImpl(y, p, q, g),
+ new DSAPrivateKey(x, p, q, g));
+ } catch (InvalidKeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/rsa/RSAKeyPairGenerator.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.rsa;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import sun.security.x509.AlgorithmId;
+import static sun.security.rsa.RSAUtil.KeyType;
+
+/**
+ * A fake RSA keypair generation.
+ */
+public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
+
+ // public exponent to use
+ private BigInteger publicExponent;
+
+ // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
+ private int keySize;
+
+ private final KeyType type;
+ private AlgorithmId rsaId;
+
+ RSAKeyPairGenerator(KeyType type, int defKeySize) {
+ this.type = type;
+ // initialize to default in case the app does not call initialize()
+ initialize(defKeySize, null);
+ }
+
+ // initialize the generator. See JCA doc
+ public void initialize(int keySize, SecureRandom random) {
+ try {
+ initialize(new RSAKeyGenParameterSpec(keySize,
+ RSAKeyGenParameterSpec.F4), random);
+ } catch (InvalidAlgorithmParameterException iape) {
+ throw new InvalidParameterException(iape.getMessage());
+ }
+ }
+
+ // second initialize method. See JCA doc.
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ if (params instanceof RSAKeyGenParameterSpec == false) {
+ throw new InvalidAlgorithmParameterException
+ ("Params must be instance of RSAKeyGenParameterSpec");
+ }
+
+ RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
+ int tmpKeySize = rsaSpec.getKeysize();
+ BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
+ AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams();
+
+ if (tmpPublicExponent == null) {
+ tmpPublicExponent = RSAKeyGenParameterSpec.F4;
+ } else {
+ if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
+ throw new InvalidAlgorithmParameterException
+ ("Public exponent must be 3 or larger");
+ }
+ if (tmpPublicExponent.bitLength() > tmpKeySize) {
+ throw new InvalidAlgorithmParameterException
+ ("Public exponent must be smaller than key size");
+ }
+ }
+
+ // do not allow unreasonably large key sizes, probably user error
+ try {
+ RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent,
+ 512, 64 * 1024);
+ } catch (InvalidKeyException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid key sizes", e);
+ }
+
+ try {
+ this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
+ } catch (ProviderException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid key parameters", e);
+ }
+
+ this.keySize = tmpKeySize;
+ this.publicExponent = tmpPublicExponent;
+ }
+
+ // generate the keypair. See JCA doc
+ public KeyPair generateKeyPair() {
+
+ // accommodate odd key sizes in case anybody wants to use them
+ BigInteger e = publicExponent;
+ if (!e.equals(RSAKeyGenParameterSpec.F4)) {
+ throw new AssertionError("Only support F4 now");
+ }
+ BigInteger p, q, n;
+
+ // Pre-calculated p and q for e == RSAKeyGenParameterSpec.F4
+ switch (keySize) {
+ case 1024:
+ p = new BigInteger("1220491537800192366196661816910427"
+ + "2375185130493819649338056226264568132442590"
+ + "2306195110391300298681932797393339089272174"
+ + "24490645345596103420476757417659909");
+
+ q = new BigInteger("8480533592205316739308384508307319"
+ + "3310632635895778398980504245932789486455154"
+ + "4265220956952343855842030266079089174423047"
+ + "7382175514060777025691485728713063");
+ break;
+ case 2048:
+ p = new BigInteger("1600840041787354447543653385760927"
+ + "2642568308955833364523274045522752644800599"
+ + "8669541532595690224703734511692014533312515"
+ + "1867029838883431415692353449578487671384896"
+ + "6611685764860941767986520897595108597563035"
+ + "4023785639802607792535812062420427283857665"
+ + "9883578590844700707106157871508280052743363"
+ + "65749456332400771");
+ q = new BigInteger("1303880717101677622201474394769850"
+ + "7257196073324816341282215626935164930077468"
+ + "5999131251387556761167658937349436378464220"
+ + "4831804147777472146628148336776639855791417"
+ + "3849903041999943901924899580268176393595653"
+ + "7357080543898614581363167420619163047562600"
+ + "6155574020606891195960345238780709194499010"
+ + "43652862954645301");
+ break;
+ case 3072:
+ p = new BigInteger("2403380417344527161525447148950543"
+ + "9379802436047502603774623852967909282895900"
+ + "7474251859703715384817150107392592636129366"
+ + "5680725148417789414447073716354703692160825"
+ + "9910929198523923851672957013786423746474670"
+ + "5285365870313877239114930859096040034848729"
+ + "0251735848703378313724697081522892607625120"
+ + "0765531003751468146539682665307123591367928"
+ + "1883284784295069877414057796300484015307336"
+ + "5167008365209621810307777651197826810474895"
+ + "858836606799546054179898997210174885200767");
+ q = new BigInteger("2046511893459993309772203642844931"
+ + "1853027469856467052942666265372903000702193"
+ + "7794121141028918655144044411085405243565188"
+ + "8318027937964509940322691121105328104450287"
+ + "0400405975394764523022670537180050051646095"
+ + "3320242109876620452477757629185501504625999"
+ + "8487187901577781067325277853462587849063313"
+ + "5364789330253471096755661110557598411108366"
+ + "1566266965711522070909440716658568303529454"
+ + "8075296935907088988560548322049196321207173"
+ + "136436923455192617031129191723631954025427");
+ break;
+ case 3073:
+ p = new BigInteger("358024230418365680745725628188289"
+ + "996969857993064124357766607077169315932503"
+ + "907030633492082868150575329278637502167157"
+ + "345572819552678004302525872656665704012432"
+ + "644868036964802792468216554458209893873320"
+ + "297608885231998895441396822219845215463819"
+ + "216163684222596923153702349718019538798623"
+ + "793830598445085650304217449539016339429747"
+ + "385490484982419227549804698120223647408926"
+ + "021549912791440569127641517442362359166673"
+ + "430151753277549861070074076802118983202554"
+ + "7683523973");
+ q = new BigInteger("169752169194244078720180277210205"
+ + "255207796420396114596943944148158798629671"
+ + "789863988428383183103705641694331073747120"
+ + "522505020908219489265190380712941311249155"
+ + "156834674079165492105570443486536740756291"
+ + "314279877766807786397193023304245520017295"
+ + "969248707516367324340822062886043618371887"
+ + "320492710434958863952407959935025922006108"
+ + "282752473898685457767312430894004833959025"
+ + "415996648289919841900071076314309778495245"
+ + "505026665971431792707247787031811654193145"
+ + "1044952887");
+ break;
+ case 4096:
+ p = new BigInteger("2985635754414679487171962796211911"
+ + "1563710734938215274736352092606404045130913"
+ + "2477365484439939846705721840432140066578525"
+ + "0762327458086280430118434094733412377416194"
+ + "8736124795243564050755767519346747209606612"
+ + "5835460937739428885308798309679495432910469"
+ + "0294757621321446003970767164933974474924664"
+ + "1513767092845098947552598109657871041666676"
+ + "2945573325433283821164032766425479703026349"
+ + "9433641551427112483593214628620450175257586"
+ + "4350119143877183562692754400346175237007314"
+ + "7121580349193179272551363894896336921717843"
+ + "3734726842184251708799134654802475890197293"
+ + "9094908310578403843742664173424031260840446"
+ + "591633359364559754200663");
+ q = new BigInteger("2279248439141087793789384816271625"
+ + "1304008816573950275844533962181244003563987"
+ + "6638461665174020058827698592331066726709304"
+ + "9231319346136709972639455506783245161859951"
+ + "6191872757335765533547033659834427437142631"
+ + "3801232751161907082392011429712327250253948"
+ + "6012497852063361866175243227579880020724881"
+ + "9393797645220239009219998518884396282407710"
+ + "7199202450846395844337846503427790307364624"
+ + "5124871273035872938616425951596065309519651"
+ + "1519189356431513094684173807318945903212527"
+ + "7712469749366620048658571121822171067675915"
+ + "5479178304648399924549334007222294762969503"
+ + "5341584429803583589276956979963609078497238"
+ + "760757619468018224491053");
+ break;
+ case 7680:
+ p = new BigInteger("7034022146817764608206409206476311"
+ + "1371065855827199565170055133179419153145313"
+ + "9446295819321510144417300286482767498463255"
+ + "3370362723164324606829434617977090251035572"
+ + "4237546099249090966627372485629853471350368"
+ + "1497807044971675189990783927066958945388379"
+ + "4004871857862380913954692362042250112646330"
+ + "0515873693830575810241740671573357342073942"
+ + "4924331206670599086552994426505996651481869"
+ + "2750320309695596383830444337180596058381417"
+ + "7804256675894755482917598033151085120879826"
+ + "5373459707672000040090469058320463160804122"
+ + "8041026671361647347262771363754358441620179"
+ + "3861076191970047581401830740749715862725492"
+ + "5750077182986169592435996668282677192000592"
+ + "8019204141383012670399208092972174321639234"
+ + "6398779487064860458178135981700487728919191"
+ + "2418625085287791733119321378648688730352488"
+ + "6446800847442687530322927871063574241918202"
+ + "1883228799435533794167861499482410970370569"
+ + "6964781912514810444018313637829915454156777"
+ + "4591735979781496237582756842195362757823524"
+ + "2054367976655738752756266147542536910268553"
+ + "7448833810249238249431673425245843356607647"
+ + "4372260685985882252621076435844355190011754"
+ + "0656637395317040751098009821385816878380790"
+ + "9017022563392158510700243843871343995665725"
+ + "9447");
+ q = new BigInteger("7006097449483280289139842436346899"
+ + "9530483972793167261845287040200424598484519"
+ + "0516644904497480849788319004016685820778949"
+ + "8514891188272714344395538114013074460410497"
+ + "8359325044727263936454825245761418873141623"
+ + "2797767712619624879346520836103128457266811"
+ + "0175147598232556414901292143389437071453369"
+ + "4867355570712858957689566849950544938172174"
+ + "9136345403774445991224311311204082279382451"
+ + "1977673518543939329498617563049052032259503"
+ + "1057378839061411322975567618416093845144604"
+ + "4563500271329350225709899627798126176885843"
+ + "9953695524756659384424971651654225913916902"
+ + "7087953078966988666226779422822854729725410"
+ + "1118666318953891716194309185187152294057704"
+ + "2509582485250984938518224243061447485603856"
+ + "0197517312286511585545481984194518805766300"
+ + "7351141154720653351520788558277866920369211"
+ + "9269193267018615410395030712426882576851775"
+ + "9240726416572698143674385203349496226355950"
+ + "0327319442530888807531774734409411628435155"
+ + "6449625936156829175453919098709371623972260"
+ + "4090598351878256110255744263233419699486705"
+ + "3658219936031243191809689036438631617494147"
+ + "8183898954195399872571907981872765548994005"
+ + "0754996819683869837696561316479950526914796"
+ + "3613549619563212818369365543951734053135086"
+ + "8593");
+ break;
+ case 7681:
+ p = new BigInteger("1051422012172516922972337796421710"
+ + "1479918158427421377774284533124281583092508"
+ + "4961153980854679659383249048667658521370629"
+ + "6404078819943386006431233653506112030196761"
+ + "7596078830067404622117784094070983115834842"
+ + "0487926993058767148294211654032287322495894"
+ + "1733666341539644761909820700670130074920230"
+ + "0423405253327351685101039824822997870642295"
+ + "8176417666723292317903368285439828460328413"
+ + "9578515412811253729224087502906626189200448"
+ + "4062549581079444644685394008569377879899377"
+ + "0578136407363616816108795867392262638913436"
+ + "2041457188733948013731661456602199370852579"
+ + "2394583215214266552642082043674873685065171"
+ + "9053703728689139119006448644148961706358756"
+ + "0498696516029596534138345596800696824976461"
+ + "8461070371773003241093580622731426623849732"
+ + "8737707046931934781383331589291927520571138"
+ + "2759511573966362005294438252298268405782746"
+ + "9642105075721912120520774388679358659061825"
+ + "8867415333830751976884165265610029632416351"
+ + "6666642762305875140340531095190000199307531"
+ + "2186952558457690950270489966695323839026041"
+ + "0797018634946454573060304991245539422899112"
+ + "9312288231966690989900334936215870198735213"
+ + "6745631923445509394027128331099748294658904"
+ + "6303809606943116678969915369410846798143779"
+ + "89187");
+ q = new BigInteger("8160183444544784072886152354850963"
+ + "2507221530634202707531181684048014518183560"
+ + "4586261698204521358487995639975786964316103"
+ + "5861955444259138806900123878887948650444640"
+ + "7062365744302695074634248387572850855758081"
+ + "9074631976865727985289995811413472254074432"
+ + "4751574514329862821405069035713821908598155"
+ + "5436571566703295992717666421591959121774983"
+ + "5913798632992394695663301960139778059658979"
+ + "4944466598070019481108421780314115410201334"
+ + "2925668957166258484312039121420100795544341"
+ + "5372918969907063685116069321551182817324799"
+ + "3347159610063964281388144113123539915925090"
+ + "2692309096312451442405059120315891913678403"
+ + "4977738880336169371406947347468157606390086"
+ + "3381587148478097717352225924672548657441771"
+ + "3887371520215341151934095945869956390140929"
+ + "3098286281540595154062683214111934217839063"
+ + "3309526631019699109621050440794920159910038"
+ + "3248965999877529393614116991972153758910967"
+ + "1712258745878268303349611893651932564447696"
+ + "9601760120187828039923387985032881949408596"
+ + "0689784023540256749586591441103043888423326"
+ + "3078541569639917739590630101701573133092711"
+ + "6157430583592378472242178997833136144409256"
+ + "3558220277370179546822023437190315852529873"
+ + "0831890147323301322699740037060134979740963"
+ + "4289");
+ break;
+ case 8192:
+ p = new BigInteger("9821669838446774374944535804569858"
+ + "0553278885576950130485823829973470553571905"
+ + "3014418421996241500307589880457361653957913"
+ + "9176499436767288125182942994089196450118944"
+ + "8701794862752733776161684616570463744619126"
+ + "4981622564763630694110472008409561205704867"
+ + "0221819623405201369630462487520858670679048"
+ + "5854008441429858453634949980424333056803703"
+ + "1205609490778445762604050796894221725977551"
+ + "1428887194691696420765173256600200430067305"
+ + "4364524177041858044598166859757042904625691"
+ + "4292728453597609683799189454690202563236931"
+ + "8171122071288244573793276051041975005528757"
+ + "0228306442708182141334279133965507583927772"
+ + "9244311696220253059281524393613278272067808"
+ + "7017494446447670799055720358621918361716353"
+ + "5018317015764698318012095108914870478138809"
+ + "8204738169777192718869484177321870413838036"
+ + "8149216482968887382371881239714335470844573"
+ + "1862934371951394070111726593305334971041399"
+ + "5517260339034138718517336990212463882142363"
+ + "9154412320743552301967162100734381046548816"
+ + "3883737645359595416600487444018399886391071"
+ + "3777667222706059170707223589163679915863781"
+ + "4662302526078720977228426750718207481384357"
+ + "7918717041190413457052439016978578217755022"
+ + "7370720979516554707297685239584071755267452"
+ + "6021894842754355160100506065457679069228273"
+ + "95209345267367982516553449135291473361");
+ q = new BigInteger("7902448465953646210110784092684896"
+ + "0265474424590294110174550047938700740921014"
+ + "1981650823416127449143596912363210790070524"
+ + "2903784112701128957948996730263815210531364"
+ + "0489145287401377007608600217628773627723381"
+ + "1194123533939872283952535576847014977682278"
+ + "9332064706645169741712060131540562788886577"
+ + "3762235020990267901959745687867018811088495"
+ + "3716021011509120447248882358515954471433808"
+ + "2782236662758287959413069553620728137831579"
+ + "2321174813204514354999978428741310035945405"
+ + "0226661395731921098764192439072425262100813"
+ + "9732949866553839713092238096261034339815187"
+ + "2832617055364163276140160068136296115910569"
+ + "9466440903693740716929166334256441926903849"
+ + "1082968246155177124035336609654226388424434"
+ + "5775783323612758615407928446164631651292743"
+ + "8428509642959278732826297890909454571009075"
+ + "7836191622138731918099379467912681177757761"
+ + "6141378131042432093843778753846726589215845"
+ + "7402160146427434508515156204064224022904659"
+ + "8645441448874409852211668374267341177082462"
+ + "7341410218867175406105046487057429530801973"
+ + "0931082058719258230993681115780999537424968"
+ + "2385515792331573549935317407789344892257264"
+ + "7464569110078675090194686816764429827739815"
+ + "0566036514181547634372488184242167294602000"
+ + "8232780963578241583529875079397308150506597"
+ + "37190564909892937290776929541076192569");
+ break;
+ default:
+ throw new AssertionError("Unknown keySize " + keySize);
+ }
+
+ n = p.multiply(q);
+
+ // phi = (p - 1) * (q - 1) must be relative prime to e
+ // otherwise RSA just won't work ;-)
+ BigInteger p1 = p.subtract(BigInteger.ONE);
+ BigInteger q1 = q.subtract(BigInteger.ONE);
+ BigInteger phi = p1.multiply(q1);
+ // generate new p and q until they work. typically
+ // the first try will succeed when using F4
+ if (e.gcd(phi).equals(BigInteger.ONE) == false) {
+ throw new AssertionError("Should not happen");
+ }
+
+ // private exponent d is the inverse of e mod phi
+ BigInteger d = e.modInverse(phi);
+
+ // 1st prime exponent pe = d mod (p - 1)
+ BigInteger pe = d.mod(p1);
+ // 2nd prime exponent qe = d mod (q - 1)
+ BigInteger qe = d.mod(q1);
+
+ // crt coefficient coeff is the inverse of q mod p
+ BigInteger coeff = q.modInverse(p);
+
+ try {
+ PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
+ PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
+ rsaId, n, e, d, p, q, pe, qe, coeff);
+ return new KeyPair(publicKey, privateKey);
+ } catch (InvalidKeyException exc) {
+ // invalid key exception only thrown for keys < 512 bit,
+ // will not happen here
+ throw new RuntimeException(exc);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/fakegen/jdk.crypto.ec/sun/security/ec/ECKeyPairGenerator.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.ec;
+
+import java.math.BigInteger;
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+
+import sun.security.util.ECUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_EC_KEY_SIZE;
+
+/**
+ * A fake EC keypair generator.
+ */
+public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
+
+ private int keySize;
+
+ public ECKeyPairGenerator() {
+ initialize(DEF_EC_KEY_SIZE, null);
+ }
+
+ @Override
+ public void initialize(int keySize, SecureRandom random) {
+ this.keySize = keySize;
+ }
+
+ @Override
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public KeyPair generateKeyPair() {
+ BigInteger s, x, y;
+ switch (keySize) {
+ case 192:
+ s = new BigInteger("144089953963995451666433763881605261867377"
+ + "0287449914970417");
+ x = new BigInteger("527580219290493448707803038403444129676461"
+ + "560927008883862");
+ y = new BigInteger("171489247081620145247240656640887886126295"
+ + "376102134763235");
+ break;
+ case 384:
+ s = new BigInteger("230878276322370828604837367594276033697165"
+ + "328633328282930557390817326627704675451851870430805"
+ + "90262886393892128915463");
+ x = new BigInteger("207573127814711182089888821916296502977037"
+ + "557291394001491584185306092085745595207966563387890"
+ + "64848861531410731137896");
+ y = new BigInteger("272903686539605964684771543637437742229808"
+ + "792287657810480793861620950159864617021540168828129"
+ + "97920015041145259782242");
+ break;
+ case 571:
+ s = new BigInteger("102950007413729156017516513076331886543538"
+ + "947044937190140406420556321983301533699021909556189"
+ + "150601557539520495361099574425100081169640300555562"
+ + "4280643194744140660275077121");
+ x = new BigInteger("640598847385582251482893323029655037929442"
+ + "593800810090252942944624854811134311418807076811195"
+ + "132373308708007447666896675761104237802118413642543"
+ + "8277858107132017492037336593");
+ y = new BigInteger("254271270803422773271985083014247202480077"
+ + "131823713050110789460550383275777195766342550786766"
+ + "080401402424961690914429074822281551140068729472439"
+ + "477216613432839953714415981");
+ break;
+ default:
+ throw new AssertionError("Unsupported keysize " + keySize);
+ }
+ ECParameterSpec ecParams = ECUtil.getECParameterSpec(null, keySize);
+ try {
+ return new KeyPair(new ECPublicKeyImpl(new ECPoint(x, y), ecParams),
+ new ECPrivateKeyImpl(s, ecParams));
+ } catch (Exception ex) {
+ throw new ProviderException(ex);
+ }
+ }
+}
--- a/test/jdk/sun/security/tools/keytool/pss/PSS.java Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * 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 8215694 8222987 8225257
- * @summary keytool cannot generate RSASSA-PSS certificates
- * @library /test/lib
- * @build java.base/sun.security.rsa.RSAKeyPairGenerator
- * @modules java.base/sun.security.util
- * java.base/sun.security.x509
- * @requires os.family != "solaris"
- * @run main PSS
- */
-
-// This test is excluded from Solaris because the 8192-bit RSA key pair
-// generator is extremely slow there.
-
-import jdk.test.lib.Asserts;
-import jdk.test.lib.SecurityTools;
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.security.DerUtils;
-import sun.security.util.ObjectIdentifier;
-import sun.security.x509.AlgorithmId;
-
-import java.io.File;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
-
-public class PSS {
-
- public static void main(String[] args) throws Exception {
-
- genkeypair("p", "-keyalg RSASSA-PSS -sigalg RSASSA-PSS")
- .shouldHaveExitValue(0);
-
- genkeypair("a", "-keyalg RSA -sigalg RSASSA-PSS -keysize 2048")
- .shouldHaveExitValue(0);
-
- genkeypair("b", "-keyalg RSA -sigalg RSASSA-PSS -keysize 4096")
- .shouldHaveExitValue(0);
-
- genkeypair("c", "-keyalg RSA -sigalg RSASSA-PSS -keysize 8192")
- .shouldHaveExitValue(0);
-
- KeyStore ks = KeyStore.getInstance(
- new File("ks"), "changeit".toCharArray());
-
- check((X509Certificate)ks.getCertificate("p"), "RSASSA-PSS",
- AlgorithmId.SHA256_oid);
-
- check((X509Certificate)ks.getCertificate("a"), "RSA",
- AlgorithmId.SHA256_oid);
-
- check((X509Certificate)ks.getCertificate("b"), "RSA",
- AlgorithmId.SHA384_oid);
-
- check((X509Certificate)ks.getCertificate("c"), "RSA",
- AlgorithmId.SHA512_oid);
-
- // More commands
- kt("-certreq -alias p -sigalg RSASSA-PSS -file p.req")
- .shouldHaveExitValue(0);
-
- kt("-gencert -alias a -sigalg RSASSA-PSS -infile p.req -outfile p.cert")
- .shouldHaveExitValue(0);
-
- kt("-importcert -alias p -file p.cert")
- .shouldHaveExitValue(0);
-
- kt("-selfcert -alias p -sigalg RSASSA-PSS")
- .shouldHaveExitValue(0);
- }
-
- static OutputAnalyzer genkeypair(String alias, String options)
- throws Exception {
- String patchArg = "-J--patch-module=java.base=" + System.getProperty("test.classes")
- + File.separator + "patches" + File.separator + "java.base";
- return kt(patchArg + " -genkeypair -alias " + alias
- + " -dname CN=" + alias + " " + options);
- }
-
- static OutputAnalyzer kt(String cmd)
- throws Exception {
- return SecurityTools.keytool("-storepass changeit -keypass changeit "
- + "-keystore ks " + cmd);
- }
-
- static void check(X509Certificate cert, String expectedKeyAlg,
- ObjectIdentifier expectedMdAlg) throws Exception {
- Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), expectedKeyAlg);
- Asserts.assertEQ(cert.getSigAlgName(), "RSASSA-PSS");
- DerUtils.checkAlg(cert.getSigAlgParams(), "000", expectedMdAlg);
- }
-}
--- a/test/jdk/sun/security/tools/keytool/pss/java.base/sun/security/rsa/RSAKeyPairGenerator.java Tue Jul 16 17:00:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.rsa;
-
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-
-import sun.security.jca.JCAUtil;
-import sun.security.x509.AlgorithmId;
-import static sun.security.rsa.RSAUtil.KeyType;
-
-/**
- * Fake RSA keypair generation.
- */
-public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
-
- // public exponent to use
- private BigInteger publicExponent;
-
- // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
- private int keySize;
-
- private final KeyType type;
- private AlgorithmId rsaId;
-
- RSAKeyPairGenerator(KeyType type, int defKeySize) {
- this.type = type;
- // initialize to default in case the app does not call initialize()
- initialize(defKeySize, null);
- }
-
- // initialize the generator. See JCA doc
- public void initialize(int keySize, SecureRandom random) {
- try {
- initialize(new RSAKeyGenParameterSpec(keySize,
- RSAKeyGenParameterSpec.F4), random);
- } catch (InvalidAlgorithmParameterException iape) {
- throw new InvalidParameterException(iape.getMessage());
- }
- }
-
- // second initialize method. See JCA doc.
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- if (params instanceof RSAKeyGenParameterSpec == false) {
- throw new InvalidAlgorithmParameterException
- ("Params must be instance of RSAKeyGenParameterSpec");
- }
-
- RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
- int tmpKeySize = rsaSpec.getKeysize();
- BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
- AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams();
-
- if (tmpPublicExponent == null) {
- tmpPublicExponent = RSAKeyGenParameterSpec.F4;
- } else {
- if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
- throw new InvalidAlgorithmParameterException
- ("Public exponent must be 3 or larger");
- }
- if (tmpPublicExponent.bitLength() > tmpKeySize) {
- throw new InvalidAlgorithmParameterException
- ("Public exponent must be smaller than key size");
- }
- }
-
- // do not allow unreasonably large key sizes, probably user error
- try {
- RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent,
- 512, 64 * 1024);
- } catch (InvalidKeyException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid key sizes", e);
- }
-
- try {
- this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
- } catch (ProviderException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid key parameters", e);
- }
-
- this.keySize = tmpKeySize;
- this.publicExponent = tmpPublicExponent;
- }
-
- // generate the keypair. See JCA doc
- public KeyPair generateKeyPair() {
-
- // accommodate odd key sizes in case anybody wants to use them
- BigInteger e = publicExponent;
- if (!e.equals(RSAKeyGenParameterSpec.F4)) {
- throw new AssertionError("Only support F4 now");
- }
- BigInteger p, q, n;
-
- // Pre-calculated p and q for e == RSAKeyGenParameterSpec.F4
- switch (keySize) {
- case 2048:
- p = new BigInteger("1600840041787354447543653385760927"
- + "2642568308955833364523274045522752644800599"
- + "8669541532595690224703734511692014533312515"
- + "1867029838883431415692353449578487671384896"
- + "6611685764860941767986520897595108597563035"
- + "4023785639802607792535812062420427283857665"
- + "9883578590844700707106157871508280052743363"
- + "65749456332400771");
- q = new BigInteger("1303880717101677622201474394769850"
- + "7257196073324816341282215626935164930077468"
- + "5999131251387556761167658937349436378464220"
- + "4831804147777472146628148336776639855791417"
- + "3849903041999943901924899580268176393595653"
- + "7357080543898614581363167420619163047562600"
- + "6155574020606891195960345238780709194499010"
- + "43652862954645301");
- break;
- case 4096:
- p = new BigInteger("2985635754414679487171962796211911"
- + "1563710734938215274736352092606404045130913"
- + "2477365484439939846705721840432140066578525"
- + "0762327458086280430118434094733412377416194"
- + "8736124795243564050755767519346747209606612"
- + "5835460937739428885308798309679495432910469"
- + "0294757621321446003970767164933974474924664"
- + "1513767092845098947552598109657871041666676"
- + "2945573325433283821164032766425479703026349"
- + "9433641551427112483593214628620450175257586"
- + "4350119143877183562692754400346175237007314"
- + "7121580349193179272551363894896336921717843"
- + "3734726842184251708799134654802475890197293"
- + "9094908310578403843742664173424031260840446"
- + "591633359364559754200663");
- q = new BigInteger("2279248439141087793789384816271625"
- + "1304008816573950275844533962181244003563987"
- + "6638461665174020058827698592331066726709304"
- + "9231319346136709972639455506783245161859951"
- + "6191872757335765533547033659834427437142631"
- + "3801232751161907082392011429712327250253948"
- + "6012497852063361866175243227579880020724881"
- + "9393797645220239009219998518884396282407710"
- + "7199202450846395844337846503427790307364624"
- + "5124871273035872938616425951596065309519651"
- + "1519189356431513094684173807318945903212527"
- + "7712469749366620048658571121822171067675915"
- + "5479178304648399924549334007222294762969503"
- + "5341584429803583589276956979963609078497238"
- + "760757619468018224491053");
- break;
- case 8192:
- p = new BigInteger("9821669838446774374944535804569858"
- + "0553278885576950130485823829973470553571905"
- + "3014418421996241500307589880457361653957913"
- + "9176499436767288125182942994089196450118944"
- + "8701794862752733776161684616570463744619126"
- + "4981622564763630694110472008409561205704867"
- + "0221819623405201369630462487520858670679048"
- + "5854008441429858453634949980424333056803703"
- + "1205609490778445762604050796894221725977551"
- + "1428887194691696420765173256600200430067305"
- + "4364524177041858044598166859757042904625691"
- + "4292728453597609683799189454690202563236931"
- + "8171122071288244573793276051041975005528757"
- + "0228306442708182141334279133965507583927772"
- + "9244311696220253059281524393613278272067808"
- + "7017494446447670799055720358621918361716353"
- + "5018317015764698318012095108914870478138809"
- + "8204738169777192718869484177321870413838036"
- + "8149216482968887382371881239714335470844573"
- + "1862934371951394070111726593305334971041399"
- + "5517260339034138718517336990212463882142363"
- + "9154412320743552301967162100734381046548816"
- + "3883737645359595416600487444018399886391071"
- + "3777667222706059170707223589163679915863781"
- + "4662302526078720977228426750718207481384357"
- + "7918717041190413457052439016978578217755022"
- + "7370720979516554707297685239584071755267452"
- + "6021894842754355160100506065457679069228273"
- + "95209345267367982516553449135291473361");
- q = new BigInteger("7902448465953646210110784092684896"
- + "0265474424590294110174550047938700740921014"
- + "1981650823416127449143596912363210790070524"
- + "2903784112701128957948996730263815210531364"
- + "0489145287401377007608600217628773627723381"
- + "1194123533939872283952535576847014977682278"
- + "9332064706645169741712060131540562788886577"
- + "3762235020990267901959745687867018811088495"
- + "3716021011509120447248882358515954471433808"
- + "2782236662758287959413069553620728137831579"
- + "2321174813204514354999978428741310035945405"
- + "0226661395731921098764192439072425262100813"
- + "9732949866553839713092238096261034339815187"
- + "2832617055364163276140160068136296115910569"
- + "9466440903693740716929166334256441926903849"
- + "1082968246155177124035336609654226388424434"
- + "5775783323612758615407928446164631651292743"
- + "8428509642959278732826297890909454571009075"
- + "7836191622138731918099379467912681177757761"
- + "6141378131042432093843778753846726589215845"
- + "7402160146427434508515156204064224022904659"
- + "8645441448874409852211668374267341177082462"
- + "7341410218867175406105046487057429530801973"
- + "0931082058719258230993681115780999537424968"
- + "2385515792331573549935317407789344892257264"
- + "7464569110078675090194686816764429827739815"
- + "0566036514181547634372488184242167294602000"
- + "8232780963578241583529875079397308150506597"
- + "37190564909892937290776929541076192569");
- break;
- default:
- throw new AssertionError("Unknown keySize " + keySize);
- }
-
- n = p.multiply(q);
-
- // phi = (p - 1) * (q - 1) must be relative prime to e
- // otherwise RSA just won't work ;-)
- BigInteger p1 = p.subtract(BigInteger.ONE);
- BigInteger q1 = q.subtract(BigInteger.ONE);
- BigInteger phi = p1.multiply(q1);
- // generate new p and q until they work. typically
- // the first try will succeed when using F4
- if (e.gcd(phi).equals(BigInteger.ONE) == false) {
- throw new AssertionError("Should not happen");
- }
-
- // private exponent d is the inverse of e mod phi
- BigInteger d = e.modInverse(phi);
-
- // 1st prime exponent pe = d mod (p - 1)
- BigInteger pe = d.mod(p1);
- // 2nd prime exponent qe = d mod (q - 1)
- BigInteger qe = d.mod(q1);
-
- // crt coefficient coeff is the inverse of q mod p
- BigInteger coeff = q.modInverse(p);
-
- try {
- PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
- PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
- rsaId, n, e, d, p, q, pe, qe, coeff);
- return new KeyPair(publicKey, privateKey);
- } catch (InvalidKeyException exc) {
- // invalid key exception only thrown for keys < 512 bit,
- // will not happen here
- throw new RuntimeException(exc);
- }
- }
-}
--- a/test/jdk/sun/security/util/FilePermCompat/CompatImpact.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/security/util/FilePermCompat/CompatImpact.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,7 +90,7 @@
.debug(testcase)
.start();
if (p.waitFor() != 0) {
- Files.copy(Paths.get("stderr." + testcase), System.out);
+ Files.copy(Paths.get(testcase + ".stderr"), System.out);
failed += testcase + " ";
}
@@ -101,7 +101,7 @@
.debug(testcase)
.start();
if (p.waitFor() != 0) {
- Files.copy(Paths.get("stderr." + testcase), System.out);
+ Files.copy(Paths.get(testcase + ".stderr"), System.out);
failed += testcase + " ";
}
@@ -114,7 +114,7 @@
.debug(testcase)
.start();
if (p.waitFor() != 0) {
- Files.copy(Paths.get("stderr." + testcase), System.out);
+ Files.copy(Paths.get(testcase + ".stderr"), System.out);
failed += testcase + " ";
}
@@ -126,7 +126,7 @@
.debug(testcase)
.start();
if (p.waitFor() != 0) {
- Files.copy(Paths.get("stderr." + testcase), System.out);
+ Files.copy(Paths.get(testcase + ".stderr"), System.out);
failed += testcase + " ";
}
@@ -138,7 +138,7 @@
.debug(testcase)
.start();
if (p.waitFor() != 0) {
- Files.copy(Paths.get("stderr." + testcase), System.out);
+ Files.copy(Paths.get(testcase + ".stderr"), System.out);
failed += testcase + " ";
}
@@ -238,6 +238,7 @@
// For my policy, f is passed into test and new MP(f)
// will be set as new policy
p.perm(new SecurityPermission("setPolicy"));
+ p.perm(new SecurityPermission("getPolicy"));
p.args(f);
break;
default:
@@ -249,7 +250,9 @@
// My own Policy impl, with only one granted permission, also not smart
// enough to know whether ProtectionDomain grants any permission
static class MP extends Policy {
+ static final Policy DEFAULT_POLICY = Policy.getPolicy();
final PermissionCollection pc;
+
MP(String f) {
FilePermission p = new FilePermission(f, "read");
pc = p.newPermissionCollection();
@@ -267,7 +270,7 @@
@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
- return pc.implies(permission);
+ return pc.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/x509/X509CertImpl/ECSigParamsVerifyWithCert.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8225745
+ * @summary Ensure ECDSA certificates with signature algorithm parameters
+ * can be verified successfully
+ * @run main ECSigParamsVerifyWithCert
+ */
+import java.io.*;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+public class ECSigParamsVerifyWithCert {
+
+ // ECDSA certificate with non-null signature parameters, i.e.
+ // Signature Algorithm: SHA256withECDSA, params unparsed,
+ // OID = 1.2.840.10045.4.3.2
+ private static String ecEntityWithSigParamsStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICXjCCAfmgAwIBAgIIHzREzASpiTowFAYIKoZIzj0EAwIGCCqGSM49AwEHMGAx\n" +
+ "IzAhBgNVBAMMGkNvcmRhIE5vZGUgSW50ZXJtZWRpYXRlIENBMQswCQYDVQQKDAJS\n" +
+ "MzEOMAwGA1UECwwFY29yZGExDzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUsw\n" +
+ "HhcNMTgwNjI1MDAwMDAwWhcNMjcwNTIwMDAwMDAwWjAxMQswCQYDVQQGEwJHQjEP\n" +
+ "MA0GA1UEBwwGTG9uZG9uMREwDwYDVQQKDAhNZWdhQ29ycDBZMBMGByqGSM49AgEG\n" +
+ "CCqGSM49AwEHA0IABG2VjWPPFnGVka3G9++Sz/GPRkAkht4BDoYTlkRz8hpwr4iu\n" +
+ "fU6NlReirLOB4LBLZcmp16xm4RYsN5ouTS7Z3wKjgcEwgb4wHQYDVR0OBBYEFBnY\n" +
+ "sikYpaSL9U8FUygbqN3sIvMOMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgGG\n" +
+ "MCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADARBgorBgEEAYOK\n" +
+ "YgEBBAMCAQQwRwYDVR0eAQH/BD0wO6A3MDWkMzAxMQswCQYDVQQGEwJHQjEPMA0G\n" +
+ "A1UEBwwGTG9uZG9uMREwDwYDVQQKDAhNZWdhQ29ycKEAMBQGCCqGSM49BAMCBggq\n" +
+ "hkjOPQMBBwNJADBGAiEAos+QzgwwH2hfOtrlLncHnoT2YXXHP4q5h01T2DRmjcMC\n" +
+ "IQDa3xZz7CkyyNO1+paAthiNVIlGwwnl4UxuYMwkAiWACw==\n" +
+ "-----END CERTIFICATE-----\n";
+
+ // ECDSA certificate with only signature algorithm oid, no parameters, i.e.
+ // Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2
+ private static String ecSigner =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICETCCAbigAwIBAgIIaHr3YTnjT8YwCgYIKoZIzj0EAwIwWDEbMBkGA1UEAwwS\n" +
+ "Q29yZGEgTm9kZSBSb290IENBMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGEx\n" +
+ "DzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUswHhcNMTcwNTIyMDAwMDAwWhcN\n" +
+ "MjcwNTIwMDAwMDAwWjBgMSMwIQYDVQQDDBpDb3JkYSBOb2RlIEludGVybWVkaWF0\n" +
+ "ZSBDQTELMAkGA1UECgwCUjMxDjAMBgNVBAsMBWNvcmRhMQ8wDQYDVQQHDAZMb25k\n" +
+ "b24xCzAJBgNVBAYTAlVLMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEA8veoCbh\n" +
+ "ZmazlyIFWjExBd8ru5OYdFW9Z9ZD5BVg/dswdKC4dlHMHe/sQ4TxFmkYNqf7DTTt\n" +
+ "ePtdHT7Eb1LGYKNkMGIwHQYDVR0OBBYEFOvuLjAVKUCuGZge2G/jfX8HosITMAsG\n" +
+ "A1UdDwQEAwIBhjAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAw\n" +
+ "DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNHADBEAiB6wr47tuC71qi6+FbY\n" +
+ "XYDTvK+QmAi5ywkFc95I9fPLaQIgIM+nNNQ50NwK610h3bG37XC2tGu+A7Dhtt2Q\n" +
+ "4nDqu30=\n" +
+ "-----END CERTIFICATE-----\n";
+
+ public static void main(String[] args) throws Exception {
+ CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ ByteArrayInputStream is
+ = new ByteArrayInputStream(ecEntityWithSigParamsStr.getBytes());
+ X509Certificate ecEntityWithSigParams = (X509Certificate)certFactory.generateCertificate(is);
+ is = new ByteArrayInputStream(ecSigner.getBytes());
+ X509Certificate ecSigner = (X509Certificate)certFactory.generateCertificate(is);
+
+ try {
+ ecEntityWithSigParams.verify(ecSigner.getPublicKey());
+ System.out.println("Test Passed: EC Cert verified");
+ } catch (Exception e) {
+ System.out.println("Failed, cannot verify EC certificate with sig params");
+ throw e;
+ }
+ }
+}
--- a/test/jdk/sun/text/resources/LocaleData Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/text/resources/LocaleData Mon Jul 22 11:08:27 2019 +0530
@@ -8322,7 +8322,15 @@
# bug #8208746
CurrencyNames//ves=Venezuelan Bol\u00edvar Soberano
-# bug# 8206879
+# bug #8206879
# For Peru decimal separator is changed to dot(.) and grouping separator is changed to comma(,)
FormatData/es_PE/NumberElements/0=.
FormatData/es_PE/NumberElements/1=,
+
+# bug #8227127
+FormatData/ja/short.Eras/0=\u7d00\u5143\u524d
+FormatData/ja/short.Eras/1=\u897f\u66a6
+FormatData/zh/short.Eras/0=\u516c\u5143\u524d
+FormatData/zh/short.Eras/1=\u516c\u5143
+FormatData/zh_TW/short.Eras/0=\u897f\u5143\u524d
+FormatData/zh_TW/short.Eras/1=\u897f\u5143
--- a/test/jdk/sun/text/resources/LocaleDataTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/text/resources/LocaleDataTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -39,7 +39,7 @@
* 8017142 8037343 8055222 8042126 8074791 8075173 8080774 8129361 8134916
* 8145136 8145952 8164784 8037111 8081643 7037368 8178872 8185841 8190918
* 8187946 8195478 8181157 8179071 8193552 8202026 8204269 8202537 8208746
- * 8209775 8221432
+ * 8209775 8221432 8227127
* @summary Verify locale data
* @modules java.base/sun.util.resources
* @modules jdk.localedata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8225715
+ * @requires vm.hasSAandCanAttach
+ * @library /test/lib
+ * @compile JShellHeapDumpTest.java
+ * @run main/timeout=240 JShellHeapDumpTest
+ */
+
+import static jdk.test.lib.Asserts.assertTrue;
+
+import java.io.IOException;
+import java.io.File;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Map;
+
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.hprof.parser.HprofReader;
+
+import jdk.jshell.JShell;
+
+public class JShellHeapDumpTest {
+
+ protected static Process process;
+
+ private static long pid;
+
+ public static void launch(String expectedMessage, List<String> toolArgs)
+ throws IOException {
+
+ try {
+ launchJshell();
+
+ System.out.println("Starting " + toolArgs.get(0) + " against " + pid);
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+
+ for (String cmd : toolArgs) {
+ launcher.addToolArg(cmd);
+ }
+
+ launcher.addToolArg("--pid=" + Long.toString(pid));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+ processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
+ System.out.println("stdout:");
+ System.out.println(output.getStdout());
+ System.out.println("stderr:");
+ System.out.println(output.getStderr());
+ output.shouldNotContain("null");
+ output.shouldHaveExitValue(0);
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ } finally {
+ if (process.isAlive()) {
+ process.destroy();
+ }
+ }
+ }
+
+ public static void launch(String expectedMessage, String... toolArgs)
+ throws IOException {
+
+ launch(expectedMessage, Arrays.asList(toolArgs));
+ }
+
+ public static void printStackTraces(String file) throws IOException {
+ try {
+ String output = HprofReader.getStack(file, 0);
+ if (!output.contains("JShellToolProvider")) {
+ throw new RuntimeException("'JShellToolProvider' missing from stdout/stderr");
+ }
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ }
+ }
+
+ public static void testHeapDump() throws IOException {
+ File dump = new File("jhsdb.jmap.heap." +
+ System.currentTimeMillis() + ".hprof");
+ if (dump.exists()) {
+ dump.delete();
+ }
+
+ launch("heap written to", "jmap",
+ "--binaryheap", "--dumpfile=" + dump.getAbsolutePath());
+
+ assertTrue(dump.exists() && dump.isFile(),
+ "Could not create dump file " + dump.getAbsolutePath());
+
+ printStackTraces(dump.getAbsolutePath());
+
+ dump.delete();
+ }
+
+ public static void launchJshell() throws IOException {
+ System.out.println("Starting Jshell");
+ String jdkPath = System.getProperty("test.jdk");
+ if (jdkPath == null) {
+ // we are not under jtreg, try env
+ Map<String, String> env = System.getenv();
+ jdkPath = env.get("TESTJAVA");
+ }
+ if (jdkPath == null) {
+ throw new RuntimeException("Can't determine jdk path neither test.jdk property no TESTJAVA env are set");
+ }
+ String osname = System.getProperty("os.name");
+ String jshell = jdkPath + ((osname.startsWith("window")) ? "/bin/jshell.exe" : "/bin/jshell");
+ process = Runtime.getRuntime().exec(jshell);
+ pid = process.pid();
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ testHeapDump();
+
+ // The test throws RuntimeException on error.
+ // IOException is thrown if Jshell can't start because of some bad
+ // environment condition
+ System.out.println("Test PASSED");
+ }
+}
--- a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8007572 8008161 8157792
+ * @bug 8007572 8008161 8157792 8224560
* @summary Test whether the TimeZone generated from JSR310 tzdb is the same
* as the one from the tz data from javazic
* @modules java.base/sun.util.calendar:+open
@@ -170,6 +170,15 @@
for (String zid : zids_new) {
ZoneInfoOld zi = toZoneInfoOld(TimeZone.getTimeZone(zid));
ZoneInfoOld ziOLD = (ZoneInfoOld)ZoneInfoOld.getTimeZone(zid);
+ /*
+ * Temporary ignoring the failing TimeZones which are having zone
+ * rules defined till year 2037 and/or above and have negative DST
+ * save time in IANA tzdata. This bug is tracked via JDK-8223388.
+ */
+ if (zid.equals("Africa/Casablanca") || zid.equals("Africa/El_Aaiun")
+ || zid.equals("Asia/Tehran") || zid.equals("Iran")) {
+ continue;
+ }
if (! zi.equalsTo(ziOLD)) {
System.out.println(zi.diffsTo(ziOLD));
throw new RuntimeException(" FAILED: " + zid);
--- a/test/jdk/sun/util/calendar/zi/tzdata/VERSION Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/VERSION Mon Jul 22 11:08:27 2019 +0530
@@ -19,4 +19,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2018g
+tzdata2019a
--- a/test/jdk/sun/util/calendar/zi/tzdata/africa Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/africa Mon Jul 22 11:08:27 2019 +0530
@@ -385,6 +385,11 @@
# See Africa/Lagos.
# Eritrea
+# See Africa/Nairobi.
+
+# Eswatini (formerly Swaziland)
+# See Africa/Johannesburg.
+
# Ethiopia
# See Africa/Nairobi.
#
@@ -868,8 +873,41 @@
# From Mohamed Essedik Najd (2018-10-26):
# Today, a Moroccan government council approved the perpetual addition
# of 60 minutes to the regular Moroccan timezone.
-# From Brian Inglis (2018-10-26):
-# http://www.maroc.ma/fr/actualites/le-conseil-de-gouvernement-adopte-un-projet-de-decret-relatif-lheure-legale-stipulant-le
+# From Matt Johnson (2018-10-28):
+# http://www.sgg.gov.ma/Portals/1/BO/2018/BO_6720-bis_Ar.pdf
+#
+# From Maamar Abdelkader (2018-11-01):
+# We usually move clocks back the previous week end and come back to the +1
+# the week end after.... The government does not announce yet the decision
+# about this temporary change. But it s 99% sure that it will be the case,
+# as in previous years. An unofficial survey was done these days, showing
+# that 64% of asked peopke are ok for moving from +1 to +0 during Ramadan.
+# https://leconomiste.com/article/1035870-enquete-l-economiste-sunergia-64-des-marocains-plebiscitent-le-gmt-pendant-ramadan
+#
+# From Paul Eggert (2018-11-01):
+# For now, guess that Morocco will fall back at 03:00 the last Sunday
+# before Ramadan, and spring forward at 02:00 the first Sunday after
+# Ramadan, as this has been the practice since 2012. To implement this,
+# transition dates for 2019 through 2037 were determined by running the
+# following program under GNU Emacs 26.1.
+# (let ((islamic-year 1440))
+# (require 'cal-islam)
+# (while (< islamic-year 1460)
+# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
+# (b (calendar-islamic-to-absolute (list 10 1 islamic-year)))
+# (sunday 0))
+# (while (/= sunday (mod (setq a (1- a)) 7)))
+# (while (/= sunday (mod b 7))
+# (setq b (1+ b)))
+# (setq a (calendar-gregorian-from-absolute a))
+# (setq b (calendar-gregorian-from-absolute b))
+# (insert
+# (format
+# (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 3:00\t-1:00\t-\n"
+# "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 2:00\t0\t-\n")
+# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
+# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
+# (setq islamic-year (+ 1 islamic-year))))
# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Morocco 1939 only - Sep 12 0:00 1:00 -
@@ -901,7 +939,7 @@
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2013 only - Jul 7 3:00 0 -
Rule Morocco 2013 only - Aug 10 2:00 1:00 -
-Rule Morocco 2013 2018 - Oct lastSun 3:00 0 -
+Rule Morocco 2013 2017 - Oct lastSun 3:00 0 -
Rule Morocco 2014 2018 - Mar lastSun 2:00 1:00 -
Rule Morocco 2014 only - Jun 28 3:00 0 -
Rule Morocco 2014 only - Aug 2 2:00 1:00 -
@@ -913,13 +951,53 @@
Rule Morocco 2017 only - Jul 2 2:00 1:00 -
Rule Morocco 2018 only - May 13 3:00 0 -
Rule Morocco 2018 only - Jun 17 2:00 1:00 -
+Rule Morocco 2019 only - May 5 3:00 0 -
+Rule Morocco 2019 only - Jun 9 2:00 1:00 -
+Rule Morocco 2020 only - Apr 19 3:00 0 -
+Rule Morocco 2020 only - May 24 2:00 1:00 -
+Rule Morocco 2021 only - Apr 11 3:00 0 -
+Rule Morocco 2021 only - May 16 2:00 1:00 -
+Rule Morocco 2022 only - Mar 27 3:00 0 -
+Rule Morocco 2022 only - May 8 2:00 1:00 -
+Rule Morocco 2023 only - Mar 19 3:00 0 -
+Rule Morocco 2023 only - Apr 23 2:00 1:00 -
+Rule Morocco 2024 only - Mar 10 3:00 0 -
+Rule Morocco 2024 only - Apr 14 2:00 1:00 -
+Rule Morocco 2025 only - Feb 23 3:00 0 -
+Rule Morocco 2025 only - Apr 6 2:00 1:00 -
+Rule Morocco 2026 only - Feb 15 3:00 0 -
+Rule Morocco 2026 only - Mar 22 2:00 1:00 -
+Rule Morocco 2027 only - Feb 7 3:00 0 -
+Rule Morocco 2027 only - Mar 14 2:00 1:00 -
+Rule Morocco 2028 only - Jan 23 3:00 0 -
+Rule Morocco 2028 only - Feb 27 2:00 1:00 -
+Rule Morocco 2029 only - Jan 14 3:00 0 -
+Rule Morocco 2029 only - Feb 18 2:00 1:00 -
+Rule Morocco 2029 only - Dec 30 3:00 0 -
+Rule Morocco 2030 only - Feb 10 2:00 1:00 -
+Rule Morocco 2030 only - Dec 22 3:00 0 -
+Rule Morocco 2031 only - Jan 26 2:00 1:00 -
+Rule Morocco 2031 only - Dec 14 3:00 0 -
+Rule Morocco 2032 only - Jan 18 2:00 1:00 -
+Rule Morocco 2032 only - Nov 28 3:00 0 -
+Rule Morocco 2033 only - Jan 9 2:00 1:00 -
+Rule Morocco 2033 only - Nov 20 3:00 0 -
+Rule Morocco 2033 only - Dec 25 2:00 1:00 -
+Rule Morocco 2034 only - Nov 5 3:00 0 -
+Rule Morocco 2034 only - Dec 17 2:00 1:00 -
+Rule Morocco 2035 only - Oct 28 3:00 0 -
+Rule Morocco 2035 only - Dec 2 2:00 1:00 -
+Rule Morocco 2036 only - Oct 19 3:00 0 -
+Rule Morocco 2036 only - Nov 23 2:00 1:00 -
+Rule Morocco 2037 only - Oct 4 3:00 0 -
+Rule Morocco 2037 only - Nov 15 2:00 1:00 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
0:00 Morocco +00/+01 1984 Mar 16
1:00 - +01 1986
- 0:00 Morocco +00/+01 2018 Oct 27
- 1:00 - +01
+ 0:00 Morocco +00/+01 2018 Oct 28 3:00
+ 0:00 Morocco +00/+01
# Western Sahara
#
@@ -934,8 +1012,8 @@
Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El Aaiún
-1:00 - -01 1976 Apr 14
- 0:00 Morocco +00/+01 2018 Oct 27
- 1:00 - +01
+ 0:00 Morocco +00/+01 2018 Oct 28 3:00
+ 0:00 Morocco +00/+01
# Mozambique
#
@@ -1092,10 +1170,20 @@
# the switch is from 01:00 to 02:00 ... [Decree No. 25/2017]
# http://www.mnec.gov.st/index.php/publicacoes/documentos/file/90-decreto-lei-n-25-2017
+# From Vadim Nasardinov (2018-12-29):
+# São Tomé and Príncipe is about to do the following on Jan 1, 2019:
+# https://www.stp-press.st/2018/12/05/governo-jesus-ja-decidiu-repor-hora-legal-sao-tomense/
+#
+# From Michael Deckers (2018-12-30):
+# https://www.legis-palop.org/download.jsp?idFile=102818
+# ... [The legal time of the country, which coincides with universal
+# coordinated time, will be restituted at 2 o'clock on day 1 of January, 2019.]
+
Zone Africa/Sao_Tome 0:26:56 - LMT 1884
-0:36:45 - LMT 1912 Jan 1 00:00u # Lisbon MT
0:00 - GMT 2018 Jan 1 01:00
- 1:00 - WAT
+ 1:00 - WAT 2019 Jan 1 02:00
+ 0:00 - GMT
# Senegal
# See Africa/Abidjan.
@@ -1126,7 +1214,7 @@
1:30 - SAST 1903 Mar
2:00 SA SAST
Link Africa/Johannesburg Africa/Maseru # Lesotho
-Link Africa/Johannesburg Africa/Mbabane # Swaziland
+Link Africa/Johannesburg Africa/Mbabane # Eswatini
#
# Marion and Prince Edward Is
# scientific station since 1947
@@ -1168,9 +1256,6 @@
2:00 Sudan CA%sT 2000 Jan 15 12:00
3:00 - EAT
-# Swaziland
-# See Africa/Johannesburg.
-
# Tanzania
# See Africa/Nairobi.
--- a/test/jdk/sun/util/calendar/zi/tzdata/asia Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/asia Mon Jul 22 11:08:27 2019 +0530
@@ -607,12 +607,82 @@
# obtained from
# http://www.hko.gov.hk/gts/time/Summertime.htm
-# From Arthur David Olson (2009-10-28):
+# From Phake Nick (2018-10-27):
+# According to Singaporean newspaper
+# http://eresources.nlb.gov.sg/newspapers/Digitised/Article/singfreepresswk19041102-1.2.37
+# the day that Hong Kong start using GMT+8 should be Oct 30, 1904.
+#
+# From Paul Eggert (2018-11-17):
+# Hong Kong had a time ball near the Marine Police Station, Tsim Sha Tsui.
+# "The ball was raised manually each day and dropped at exactly 1pm
+# (except on Sundays and Government holidays)."
+# Dyson AD. From Time Ball to Atomic Clock. Hong Kong Government. 1983.
+# <https://www.hko.gov.hk/publica/gen_pub/timeball_atomic_clock.pdf>
+# "From 1904 October 30 the time-ball at Hong Kong has been dropped by order
+# of the Governor of the Colony at 17h 0m 0s G.M.T., which is 23m 18s.14 in
+# advance of 1h 0m 0s of Hong Kong mean time."
+# Hollis HP. Universal Time, Longitudes, and Geodesy. Mon Not R Astron Soc.
+# 1905-02-10;65(4):405-6. https://doi.org/10.1093/mnras/65.4.382
+#
+# From Joseph Myers (2018-11-18):
+# An astronomer before 1925 referring to GMT would have been using the old
+# astronomical convention where the day started at noon, not midnight.
+#
+# From Steve Allen (2018-11-17):
+# Meteorological Observations made at the Hongkong Observatory in the year 1904
+# page 4 <https://books.google.com/books?id=kgw5AQAAMAAJ&pg=RA4-PA4>
+# ... the log of drop times in Table II shows that on Sunday 1904-10-30 the
+# ball was dropped. So that looks like a special case drop for the sake
+# of broadcasting the new local time.
+#
+# From Phake Nick (2018-11-18):
+# According to The Hong Kong Weekly Press, 1904-10-29, p.324, the
+# governor of Hong Kong at the time stated that "We are further desired to
+# make it known that the change will be effected by firing the gun and by the
+# dropping of the Ball at 23min. 18sec. before one."
+# From Paul Eggert (2018-11-18):
+# See <https://mmis.hkpl.gov.hk> for this; unfortunately Flash is required.
+
+# From Phake Nick (2018-10-26):
+# I went to check microfilm records stored at Hong Kong Public Library....
+# on September 30 1941, according to Ta Kung Pao (Hong Kong edition), it was
+# stated that fallback would occur on the next day (the 1st)'s "03:00 am (Hong
+# Kong Time 04:00 am)" and the clock will fall back for a half hour. (03:00
+# probably refer to the time commonly used in mainland China at the time given
+# the paper's background) ... the sunrise/sunset time given by South China
+# Morning Post for October 1st was indeed moved by half an hour compares to
+# before. After that, in December, the battle to capture Hong Kong started and
+# the library doesn't seems to have any record stored about press during that
+# period of time. Some media resumed publication soon after that within the
+# same month, but there were not much information about time there. Later they
+# started including a radio program guide when they restored radio service,
+# explicitly mentioning it use Tokyo standard time, and later added a note
+# saying it's half an hour ahead of the old Hong Kong standard time, and it
+# also seems to indicate that Hong Kong was not using GMT+8 when it was
+# captured by Japan.
+#
+# Image of related sections on newspaper:
+# * 1941-09-30, Ta Kung Pao (Hong Kong), "Winter Time start tomorrow".
+# https://i.imgur.com/6waY51Z.jpg (Chinese)
+# * 1941-09-29, South China Morning Post, Information on sunrise/sunset
+# time and other things for September 30 and October 1.
+# https://i.imgur.com/kCiUR78.jpg
+# * 1942-02-05. The Hong Kong News, Radio Program Guide.
+# https://i.imgur.com/eVvDMzS.jpg
+# * 1941-06-14. Hong Kong Daily Press, Daylight Saving from 3am Tomorrow.
+# https://i.imgur.com/05KkvtC.png
+# * 1941-09-30, Hong Kong Daily Press, Winter Time Warning.
+# https://i.imgur.com/dge4kFJ.png
+# Also, the Liberation day of Hong Kong after WWII which British rule
+# over the territory resumed was August 30, 1945, which I think should
+# be the termination date for the use of JST in the territory....
+
+# From Paul Eggert (2018-11-17):
# Here are the dates given at
-# http://www.hko.gov.hk/gts/time/Summertime.htm
-# as of 2009-10-28:
+# https://www.hko.gov.hk/gts/time/Summertime.htm
+# as of 2014-06-19:
# Year Period
-# 1941 1 Apr to 30 Sep
+# 1941 15 Jun to 30 Sep
# 1942 Whole year
# 1943 Whole year
# 1944 Whole year
@@ -623,7 +693,7 @@
# 1949 3 Apr to 30 Oct
# 1950 2 Apr to 29 Oct
# 1951 1 Apr to 28 Oct
-# 1952 6 Apr to 25 Oct
+# 1952 6 Apr to 2 Nov
# 1953 5 Apr to 1 Nov
# 1954 21 Mar to 31 Oct
# 1955 20 Mar to 6 Nov
@@ -652,25 +722,25 @@
# 1978 Nil
# 1979 13 May to 21 Oct
# 1980 to Now Nil
-# The page does not give start or end times of day.
-# The page does not give a start date for 1942.
-# The page does not givw an end date for 1945.
-# The Japanese occupation of Hong Kong began on 1941-12-25.
-# The Japanese surrender of Hong Kong was signed 1945-09-15.
-# For lack of anything better, use start of those days as the transition times.
+# The page does not give times of day for transitions,
+# or dates for the 1942 and 1945 transitions.
+# The Japanese occupation of Hong Kong began 1941-12-25.
+# The Japanese surrender of Hong Kong was signed 1945-09-16; see:
+# Heaver S. The days after the Pacific war ended: unsettling times
+# in Hong Kong. Post Magazine. 2016-06-13.
+# https://www.scmp.com/magazines/post-magazine/article/1852990/days-after-pacific-war-ended-unsettling-times-hong-kong
+# For lack of anything better, use start of those days as the
+# transition times.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule HK 1941 only - Apr 1 3:30 1:00 S
-Rule HK 1941 only - Sep 30 3:30 0 -
Rule HK 1946 only - Apr 20 3:30 1:00 S
Rule HK 1946 only - Dec 1 3:30 0 -
Rule HK 1947 only - Apr 13 3:30 1:00 S
Rule HK 1947 only - Dec 30 3:30 0 -
Rule HK 1948 only - May 2 3:30 1:00 S
Rule HK 1948 1951 - Oct lastSun 3:30 0 -
-Rule HK 1952 only - Oct 25 3:30 0 -
+Rule HK 1952 1953 - Nov Sun>=1 3:30 0 -
Rule HK 1949 1953 - Apr Sun>=1 3:30 1:00 S
-Rule HK 1953 only - Nov 1 3:30 0 -
Rule HK 1954 1964 - Mar Sun>=18 3:30 1:00 S
Rule HK 1954 only - Oct 31 3:30 0 -
Rule HK 1955 1964 - Nov Sun>=1 3:30 0 -
@@ -680,9 +750,11 @@
Rule HK 1979 only - May Sun>=8 3:30 1:00 S
Rule HK 1979 only - Oct Sun>=16 3:30 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30
- 8:00 HK HK%sT 1941 Dec 25
- 9:00 - JST 1945 Sep 15
+Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 0:36:42
+ 8:00 - HKT 1941 Jun 15 3:30
+ 8:00 1:00 HKST 1941 Oct 1 4:00
+ 8:30 - HKT 1941 Dec 25
+ 9:00 - JST 1945 Sep 16
8:00 HK HK%sT
###############################################################################
@@ -1078,6 +1150,16 @@
# India
+# British astronomer Henry Park Hollis disliked India Standard Time's offset:
+# "A new time system has been proposed for India, Further India, and Burmah.
+# The scheme suggested is that the times of the meridians 5½ and 6½ hours
+# east of Greenwich should be adopted in these territories. No reason is
+# given why hourly meridians five hours and six hours east should not be
+# chosen; a plan which would bring the time of India into harmony with
+# that of almost the whole of the civilised world."
+# Hollis HP. Universal Time, Longitudes, and Geodesy. Mon Not R Astron Soc.
+# 1905-02-10;65(4):405-6. https://doi.org/10.1093/mnras/65.4.382
+
# From Ian P. Beacock, in "A brief history of (modern) time", The Atlantic
# https://www.theatlantic.com/technology/archive/2015/12/the-creation-of-modern-time/421419/
# (2015-12-22):
@@ -1248,12 +1330,65 @@
# leap year calculation involved. There has never been any serious
# plan to change that law....
#
-# From Paul Eggert (2006-03-22):
+# From Paul Eggert (2018-11-30):
# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
-# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
-# stopping after 2037 when 32-bit time_t's overflow.
-# That cal-persia used Birashk's approximation, which disagrees with the solar
-# calendar predictions for the year 2025, so I corrected those dates by hand.
+# I used the following code in GNU Emacs 26.1 to generate the "Rule Iran"
+# lines from 2008 through 2087. Emacs 26.1 uses Ed Reingold's
+# cal-persia implementation of Birashk's approximation, which in the
+# 2008-2087 range disagrees with the the astronomical Persian calendar
+# for Persian years 1404 (Gregorian 2025) and 1437 (Gregorian 2058),
+# so the following code special-case those years. See Table 15.1, page 264, of:
+# Edward M. Reingold and Nachum Dershowitz, Calendrical Calculations:
+# The Ultimate Edition, Cambridge University Press (2018).
+# https://www.cambridge.org/fr/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition
+# Page 258, footnote 2, of this book says there is some dispute over what will
+# happen in 2091 (and some other years after that), so this code
+# stops in 2087, as 2088 and 2089 agree with the "max" rule below.
+# (cl-loop
+# initially (require 'cal-persia)
+# with first-persian-year = 1387
+# with last-persian-year = 1466
+# ;; Exceptional years in the above range,
+# ;; from Reingold & Dershowitz Table 15.1, page 264:
+# with exceptional-persian-years = '(1404 1437)
+# with range-start = nil
+# for persian-year from first-persian-year to last-persian-year
+# do
+# (let*
+# ((exceptional-year-offset
+# (if (member persian-year exceptional-persian-years) 1 0))
+# (beg-dst-absolute
+# (+ (calendar-persian-to-absolute (list 1 1 persian-year))
+# exceptional-year-offset))
+# (end-dst-absolute
+# (+ (calendar-persian-to-absolute (list 6 30 persian-year))
+# exceptional-year-offset))
+# (next-year-beg-dst-absolute
+# (+ (calendar-persian-to-absolute (list 1 1 (1+ persian-year)))
+# (if (member (1+ persian-year) exceptional-persian-years) 1 0)))
+# (beg-dst (calendar-gregorian-from-absolute beg-dst-absolute))
+# (end-dst (calendar-gregorian-from-absolute end-dst-absolute))
+# (next-year-beg-dst (calendar-gregorian-from-absolute
+# next-year-beg-dst-absolute))
+# (year (calendar-extract-year beg-dst))
+# (range-end (if range-start year "only")))
+# (setq range-start (or range-start year))
+# (when (or (/= (calendar-extract-day beg-dst)
+# (calendar-extract-day next-year-beg-dst))
+# (= persian-year last-persian-year))
+# (insert
+# (format
+# "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t1:00\t-\n"
+# range-start range-end
+# (calendar-month-name (calendar-extract-month beg-dst) t)
+# (calendar-extract-day beg-dst)))
+# (insert
+# (format
+# "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t0\t-\n"
+# range-start range-end
+# (calendar-month-name (calendar-extract-month end-dst) t)
+# (calendar-extract-day end-dst)))
+# (setq range-start nil))))
#
# From Oscar van Vlijmen (2005-03-30), writing about future
# discrepancies between cal-persia and the Iranian calendar:
@@ -1288,61 +1423,113 @@
# thirtieth day of Shahrivar.
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Iran 1978 1980 - Mar 21 0:00 1:00 -
-Rule Iran 1978 only - Oct 21 0:00 0 -
-Rule Iran 1979 only - Sep 19 0:00 0 -
-Rule Iran 1980 only - Sep 23 0:00 0 -
-Rule Iran 1991 only - May 3 0:00 1:00 -
-Rule Iran 1992 1995 - Mar 22 0:00 1:00 -
-Rule Iran 1991 1995 - Sep 22 0:00 0 -
-Rule Iran 1996 only - Mar 21 0:00 1:00 -
-Rule Iran 1996 only - Sep 21 0:00 0 -
-Rule Iran 1997 1999 - Mar 22 0:00 1:00 -
-Rule Iran 1997 1999 - Sep 22 0:00 0 -
-Rule Iran 2000 only - Mar 21 0:00 1:00 -
-Rule Iran 2000 only - Sep 21 0:00 0 -
-Rule Iran 2001 2003 - Mar 22 0:00 1:00 -
-Rule Iran 2001 2003 - Sep 22 0:00 0 -
-Rule Iran 2004 only - Mar 21 0:00 1:00 -
-Rule Iran 2004 only - Sep 21 0:00 0 -
-Rule Iran 2005 only - Mar 22 0:00 1:00 -
-Rule Iran 2005 only - Sep 22 0:00 0 -
-Rule Iran 2008 only - Mar 21 0:00 1:00 -
-Rule Iran 2008 only - Sep 21 0:00 0 -
-Rule Iran 2009 2011 - Mar 22 0:00 1:00 -
-Rule Iran 2009 2011 - Sep 22 0:00 0 -
-Rule Iran 2012 only - Mar 21 0:00 1:00 -
-Rule Iran 2012 only - Sep 21 0:00 0 -
-Rule Iran 2013 2015 - Mar 22 0:00 1:00 -
-Rule Iran 2013 2015 - Sep 22 0:00 0 -
-Rule Iran 2016 only - Mar 21 0:00 1:00 -
-Rule Iran 2016 only - Sep 21 0:00 0 -
-Rule Iran 2017 2019 - Mar 22 0:00 1:00 -
-Rule Iran 2017 2019 - Sep 22 0:00 0 -
-Rule Iran 2020 only - Mar 21 0:00 1:00 -
-Rule Iran 2020 only - Sep 21 0:00 0 -
-Rule Iran 2021 2023 - Mar 22 0:00 1:00 -
-Rule Iran 2021 2023 - Sep 22 0:00 0 -
-Rule Iran 2024 only - Mar 21 0:00 1:00 -
-Rule Iran 2024 only - Sep 21 0:00 0 -
-Rule Iran 2025 2027 - Mar 22 0:00 1:00 -
-Rule Iran 2025 2027 - Sep 22 0:00 0 -
-Rule Iran 2028 2029 - Mar 21 0:00 1:00 -
-Rule Iran 2028 2029 - Sep 21 0:00 0 -
-Rule Iran 2030 2031 - Mar 22 0:00 1:00 -
-Rule Iran 2030 2031 - Sep 22 0:00 0 -
-Rule Iran 2032 2033 - Mar 21 0:00 1:00 -
-Rule Iran 2032 2033 - Sep 21 0:00 0 -
-Rule Iran 2034 2035 - Mar 22 0:00 1:00 -
-Rule Iran 2034 2035 - Sep 22 0:00 0 -
+Rule Iran 1978 1980 - Mar 20 24:00 1:00 -
+Rule Iran 1978 only - Oct 20 24:00 0 -
+Rule Iran 1979 only - Sep 18 24:00 0 -
+Rule Iran 1980 only - Sep 22 24:00 0 -
+Rule Iran 1991 only - May 2 24:00 1:00 -
+Rule Iran 1992 1995 - Mar 21 24:00 1:00 -
+Rule Iran 1991 1995 - Sep 21 24:00 0 -
+Rule Iran 1996 only - Mar 20 24:00 1:00 -
+Rule Iran 1996 only - Sep 20 24:00 0 -
+Rule Iran 1997 1999 - Mar 21 24:00 1:00 -
+Rule Iran 1997 1999 - Sep 21 24:00 0 -
+Rule Iran 2000 only - Mar 20 24:00 1:00 -
+Rule Iran 2000 only - Sep 20 24:00 0 -
+Rule Iran 2001 2003 - Mar 21 24:00 1:00 -
+Rule Iran 2001 2003 - Sep 21 24:00 0 -
+Rule Iran 2004 only - Mar 20 24:00 1:00 -
+Rule Iran 2004 only - Sep 20 24:00 0 -
+Rule Iran 2005 only - Mar 21 24:00 1:00 -
+Rule Iran 2005 only - Sep 21 24:00 0 -
+Rule Iran 2008 only - Mar 20 24:00 1:00 -
+Rule Iran 2008 only - Sep 20 24:00 0 -
+Rule Iran 2009 2011 - Mar 21 24:00 1:00 -
+Rule Iran 2009 2011 - Sep 21 24:00 0 -
+Rule Iran 2012 only - Mar 20 24:00 1:00 -
+Rule Iran 2012 only - Sep 20 24:00 0 -
+Rule Iran 2013 2015 - Mar 21 24:00 1:00 -
+Rule Iran 2013 2015 - Sep 21 24:00 0 -
+Rule Iran 2016 only - Mar 20 24:00 1:00 -
+Rule Iran 2016 only - Sep 20 24:00 0 -
+Rule Iran 2017 2019 - Mar 21 24:00 1:00 -
+Rule Iran 2017 2019 - Sep 21 24:00 0 -
+Rule Iran 2020 only - Mar 20 24:00 1:00 -
+Rule Iran 2020 only - Sep 20 24:00 0 -
+Rule Iran 2021 2023 - Mar 21 24:00 1:00 -
+Rule Iran 2021 2023 - Sep 21 24:00 0 -
+Rule Iran 2024 only - Mar 20 24:00 1:00 -
+Rule Iran 2024 only - Sep 20 24:00 0 -
+Rule Iran 2025 2027 - Mar 21 24:00 1:00 -
+Rule Iran 2025 2027 - Sep 21 24:00 0 -
+Rule Iran 2028 2029 - Mar 20 24:00 1:00 -
+Rule Iran 2028 2029 - Sep 20 24:00 0 -
+Rule Iran 2030 2031 - Mar 21 24:00 1:00 -
+Rule Iran 2030 2031 - Sep 21 24:00 0 -
+Rule Iran 2032 2033 - Mar 20 24:00 1:00 -
+Rule Iran 2032 2033 - Sep 20 24:00 0 -
+Rule Iran 2034 2035 - Mar 21 24:00 1:00 -
+Rule Iran 2034 2035 - Sep 21 24:00 0 -
+Rule Iran 2036 2037 - Mar 20 24:00 1:00 -
+Rule Iran 2036 2037 - Sep 20 24:00 0 -
+Rule Iran 2038 2039 - Mar 21 24:00 1:00 -
+Rule Iran 2038 2039 - Sep 21 24:00 0 -
+Rule Iran 2040 2041 - Mar 20 24:00 1:00 -
+Rule Iran 2040 2041 - Sep 20 24:00 0 -
+Rule Iran 2042 2043 - Mar 21 24:00 1:00 -
+Rule Iran 2042 2043 - Sep 21 24:00 0 -
+Rule Iran 2044 2045 - Mar 20 24:00 1:00 -
+Rule Iran 2044 2045 - Sep 20 24:00 0 -
+Rule Iran 2046 2047 - Mar 21 24:00 1:00 -
+Rule Iran 2046 2047 - Sep 21 24:00 0 -
+Rule Iran 2048 2049 - Mar 20 24:00 1:00 -
+Rule Iran 2048 2049 - Sep 20 24:00 0 -
+Rule Iran 2050 2051 - Mar 21 24:00 1:00 -
+Rule Iran 2050 2051 - Sep 21 24:00 0 -
+Rule Iran 2052 2053 - Mar 20 24:00 1:00 -
+Rule Iran 2052 2053 - Sep 20 24:00 0 -
+Rule Iran 2054 2055 - Mar 21 24:00 1:00 -
+Rule Iran 2054 2055 - Sep 21 24:00 0 -
+Rule Iran 2056 2057 - Mar 20 24:00 1:00 -
+Rule Iran 2056 2057 - Sep 20 24:00 0 -
+Rule Iran 2058 2059 - Mar 21 24:00 1:00 -
+Rule Iran 2058 2059 - Sep 21 24:00 0 -
+Rule Iran 2060 2062 - Mar 20 24:00 1:00 -
+Rule Iran 2060 2062 - Sep 20 24:00 0 -
+Rule Iran 2063 only - Mar 21 24:00 1:00 -
+Rule Iran 2063 only - Sep 21 24:00 0 -
+Rule Iran 2064 2066 - Mar 20 24:00 1:00 -
+Rule Iran 2064 2066 - Sep 20 24:00 0 -
+Rule Iran 2067 only - Mar 21 24:00 1:00 -
+Rule Iran 2067 only - Sep 21 24:00 0 -
+Rule Iran 2068 2070 - Mar 20 24:00 1:00 -
+Rule Iran 2068 2070 - Sep 20 24:00 0 -
+Rule Iran 2071 only - Mar 21 24:00 1:00 -
+Rule Iran 2071 only - Sep 21 24:00 0 -
+Rule Iran 2072 2074 - Mar 20 24:00 1:00 -
+Rule Iran 2072 2074 - Sep 20 24:00 0 -
+Rule Iran 2075 only - Mar 21 24:00 1:00 -
+Rule Iran 2075 only - Sep 21 24:00 0 -
+Rule Iran 2076 2078 - Mar 20 24:00 1:00 -
+Rule Iran 2076 2078 - Sep 20 24:00 0 -
+Rule Iran 2079 only - Mar 21 24:00 1:00 -
+Rule Iran 2079 only - Sep 21 24:00 0 -
+Rule Iran 2080 2082 - Mar 20 24:00 1:00 -
+Rule Iran 2080 2082 - Sep 20 24:00 0 -
+Rule Iran 2083 only - Mar 21 24:00 1:00 -
+Rule Iran 2083 only - Sep 21 24:00 0 -
+Rule Iran 2084 2086 - Mar 20 24:00 1:00 -
+Rule Iran 2084 2086 - Sep 20 24:00 0 -
+Rule Iran 2087 only - Mar 21 24:00 1:00 -
+Rule Iran 2087 only - Sep 21 24:00 0 -
#
-# The following rules are approximations starting in the year 2038.
-# These are the best post-2037 approximations available, given the
-# restrictions of a single rule using a Gregorian-based data format.
+# The following rules are approximations starting in the year 2088.
+# These are the best post-2088 approximations available, given the
+# restrictions of a single rule using ordinary Gregorian dates.
# At some point this table will need to be extended, though quite
# possibly Iran will change the rules first.
-Rule Iran 2036 max - Mar 21 0:00 1:00 -
-Rule Iran 2036 max - Sep 21 0:00 0 -
+Rule Iran 2088 max - Mar 20 24:00 1:00 -
+Rule Iran 2088 max - Sep 20 24:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Tehran 3:25:44 - LMT 1916
@@ -1454,6 +1641,24 @@
Rule Zion 1974 only - Oct 13 0:00 0 S
Rule Zion 1975 only - Apr 20 0:00 1:00 D
Rule Zion 1975 only - Aug 31 0:00 0 S
+
+# From Alois Treindl (2019-03-06):
+# http://www.moin.gov.il/Documents/שעון קיץ/clock-50-years-7-2014.pdf
+# From Isaac Starkman (2019-03-06):
+# Summer time was in that period in 1980 and 1984, see
+# https://www.ynet.co.il/articles/0,7340,L-3951073,00.html
+# You can of course read it in translation.
+# I checked the local newspapers for that years.
+# It started on midnight and end at 01.00 am.
+# From Paul Eggert (2019-03-06):
+# Also see this thread about the moin.gov.il URL:
+# https://mm.icann.org/pipermail/tz/2018-November/027194.html
+Rule Zion 1980 only - Aug 2 0:00 1:00 D
+Rule Zion 1980 only - Sep 13 1:00 0 S
+Rule Zion 1984 only - May 5 0:00 1:00 D
+Rule Zion 1984 only - Aug 25 1:00 0 S
+
+# From Shanks & Pottenger:
Rule Zion 1985 only - Apr 14 0:00 1:00 D
Rule Zion 1985 only - Sep 15 0:00 0 S
Rule Zion 1986 only - May 18 0:00 1:00 D
@@ -1712,7 +1917,9 @@
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
9:00 Japan J%sT
-# Since 1938, all Japanese possessions have been like Asia/Tokyo.
+# Since 1938, all Japanese possessions have been like Asia/Tokyo,
+# except that Truk (Chuuk), Ponape (Pohnpei), and Jaluit (Kosrae) did not
+# switch from +10 to +09 until 1941-04-01; see the 'australasia' file.
# Jordan
#
@@ -2002,8 +2209,10 @@
# and in Byalokoz) lists Ural river (plus 10 versts on its left bank) in
# the third time belt (before 1930 this means +03).
-# From Paul Eggert (2016-12-06):
-# The tables below reflect Golosunov's remarks, with exceptions as noted.
+# From Alexander Konzurovski (2018-12-20):
+# Qyzyolrda Region (Asia/Qyzylorda) is changing its time zone from
+# UTC+6 to UTC+5 effective December 21st, 2018. The legal document is
+# located here: http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
#
@@ -2017,8 +2226,6 @@
6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s
6:00 - +06
# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
-# This currently includes Qostanay (aka Kostanay, Kustanay) (KZ-KUS);
-# see comments below.
Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
5:00 - +05 1981 Apr 1
@@ -2029,21 +2236,22 @@
5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s
6:00 RussiaAsia +06/+07 1992 Mar 29 2:00s
5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
+ 6:00 - +06 2018 Dec 21 0:00
+ 5:00 - +05
+#
+# Qostanay (aka Kostanay, Kustanay) (KZ-KUS)
+# The 1991/2 rules are unclear partly because of the 1997 Turgai
+# reorganization.
+Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2
+ 4:00 - +04 1930 Jun 21
+ 5:00 - +05 1981 Apr 1
+ 5:00 1:00 +06 1981 Oct 1
+ 6:00 - +06 1982 Apr 1
+ 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s
+ 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s
+ 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
6:00 - +06
-# The following zone is like Asia/Qyzylorda except for being one
-# hour earlier from 1991-09-29 to 1992-03-29. The 1991/2 rules for
-# Qostanay are unclear partly because of the 1997 Turgai
-# reorganization, so this zone is commented out for now.
-#Zone Asia/Qostanay 4:14:20 - LMT 1924 May 2
-# 4:00 - +04 1930 Jun 21
-# 5:00 - +05 1981 Apr 1
-# 5:00 1:00 +06 1981 Oct 1
-# 6:00 - +06 1982 Apr 1
-# 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s
-# 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s
-# 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s
-# 6:00 - +06
-#
+
# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
@@ -2137,21 +2345,43 @@
# started at June 1 in that year. For another example, the article in
# 1988 said that DST started at 2:00 AM in that year.
+# From Phake Nick (2018-10-27):
+# 1. According to official announcement from Korean government, the DST end
+# date in South Korea should be
+# 1955-09-08 without specifying time
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027977557
+# 1956-09-29 without specifying time
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027978341
+# 1957-09-21 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027979690#3
+# 1958-09-20 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027981189
+# 1959-09-19 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027982974#2
+# 1960-09-17 24 o'clock
+# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0028044104
+# ...
+# 2.... https://namu.wiki/w/대한민국%20표준시 ... [says]
+# when Korea was using GMT+8:30 as standard time, the international
+# aviation/marine/meteorological industry in the country refused to
+# follow and continued to use GMT+9:00 for interoperability.
+
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule ROK 1948 only - Jun 1 0:00 1:00 D
-Rule ROK 1948 only - Sep 13 0:00 0 S
-Rule ROK 1949 only - Apr 3 0:00 1:00 D
-Rule ROK 1949 1951 - Sep Sun>=8 0:00 0 S
-Rule ROK 1950 only - Apr 1 0:00 1:00 D
-Rule ROK 1951 only - May 6 0:00 1:00 D
-Rule ROK 1955 only - May 5 0:00 1:00 D
-Rule ROK 1955 only - Sep 9 0:00 0 S
-Rule ROK 1956 only - May 20 0:00 1:00 D
-Rule ROK 1956 only - Sep 30 0:00 0 S
-Rule ROK 1957 1960 - May Sun>=1 0:00 1:00 D
-Rule ROK 1957 1960 - Sep Sun>=18 0:00 0 S
-Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D
-Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
+Rule ROK 1948 only - Jun 1 0:00 1:00 D
+Rule ROK 1948 only - Sep 12 24:00 0 S
+Rule ROK 1949 only - Apr 3 0:00 1:00 D
+Rule ROK 1949 1951 - Sep Sat>=7 24:00 0 S
+Rule ROK 1950 only - Apr 1 0:00 1:00 D
+Rule ROK 1951 only - May 6 0:00 1:00 D
+Rule ROK 1955 only - May 5 0:00 1:00 D
+Rule ROK 1955 only - Sep 8 24:00 0 S
+Rule ROK 1956 only - May 20 0:00 1:00 D
+Rule ROK 1956 only - Sep 29 24:00 0 S
+Rule ROK 1957 1960 - May Sun>=1 0:00 1:00 D
+Rule ROK 1957 1960 - Sep Sat>=17 24:00 0 S
+Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D
+Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
# From Paul Eggert (2016-08-23):
# The Korean Wikipedia entry gives the following sources for UT offsets:
@@ -2880,9 +3110,15 @@
# the official website, though the decree did not specify the exact
# time of the time shift.
# http://www.palestinecabinet.gov.ps/Website/AR/NDecrees/ViewFile.ashx?ID=e7a42ab7-ee23-435a-b9c8-a4f7e81f3817
+
+# From Even Scharning (2019-03-23):
+# DST in Palestine will start on 30 March this year, not 23 March as the time
+# zone database predicted.
+# https://ramallah.news/post/123610
#
-# From Paul Eggert (2018-03-16):
-# For 2016 on, predict spring transitions on March's fourth Saturday at 01:00.
+# From Tim Parenti (2019-03-23):
+# Combining this with the rules observed since 2016, adjust our spring
+# transition guess to Mar Sat>=24.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2913,7 +3149,7 @@
Rule Palestine 2013 only - Sep Fri>=21 0:00 0 -
Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 -
Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S
-Rule Palestine 2016 max - Mar Sat>=22 1:00 1:00 S
+Rule Palestine 2016 max - Mar Sat>=24 1:00 1:00 S
Rule Palestine 2016 max - Oct lastSat 1:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -2941,6 +3177,11 @@
# no information
# Philippines
+
+# From Paul Eggert (2018-11-18):
+# The Spanish initially used American (west-of-Greenwich) time.
+# It is unknown what time Manila kept when the British occupied it from
+# 1762-10-06 through 1764-04; for now assume it kept American time.
# On 1844-08-16, Narciso Clavería, governor-general of the
# Philippines, issued a proclamation announcing that 1844-12-30 was to
# be immediately followed by 1845-01-01; see R.H. van Gent's
@@ -3026,8 +3267,8 @@
# going to run on Higgins Time.' And so, until last year, it did." See:
# Antar E. Dinner at When? Saudi Aramco World, 1969 March/April. 2-3.
# http://archive.aramcoworld.com/issue/196902/dinner.at.when.htm
-# newspapers.com says a similar story about Higgins was published in the Port
-# Angeles (WA) Evening News, 1965-03-10, page 5, but I lack access to the text.
+# Also see: Antar EN. Arabian flying is confusing.
+# Port Angeles (WA) Evening News. 1965-03-10. page 3.
#
# The TZ database cannot represent quasi-solar time; airline time is the best
# we can do. The 1946 foreign air news digest of the U.S. Civil Aeronautics
@@ -3400,5 +3641,17 @@
8:00 - +08 1975 Jun 13
7:00 - +07
+# From Paul Eggert (2019-02-19):
+#
+# The Ho Chi Minh entry suffices for most purposes as it agrees with all of
+# Vietnam since 1975-06-13. Presumably clocks often changed in south Vietnam
+# in the early 1970s as locations changed hands during the war; however the
+# details are unknown and would likely be too voluminous for this database.
+#
+# For timestamps in north Vietnam back to 1970 (the tzdb cutoff),
+# use Asia/Bangkok; see the VN entries in the file zone1970.tab.
+# For timestamps before 1970, see Asia/Hanoi in the file 'backzone'.
+
+
# Yemen
# See Asia/Riyadh.
--- a/test/jdk/sun/util/calendar/zi/tzdata/australasia Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/australasia Mon Jul 22 11:08:27 2019 +0530
@@ -423,10 +423,44 @@
# it is uninhabited.
# Guam
+
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# http://guamlegislature.com/Public_Laws_5th/PL05-025.pdf
+# http://documents.guam.gov/wp-content/uploads/E.O.-59-7-Guam-Daylight-Savings-Time-May-6-1959.pdf
+Rule Guam 1959 only - Jun 27 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-61-5-Revocation-of-Daylight-Saving-Time-and-Restoratio.pdf
+Rule Guam 1961 only - Jan 29 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-67-13-Guam-Daylight-Savings-Time.pdf
+Rule Guam 1967 only - Sep 1 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-69-2-Repeal-of-Guam-Daylight-Saving-Time.pdf
+Rule Guam 1969 only - Jan 26 0:01 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-69-10-Guam-Daylight-Saving-Time.pdf
+Rule Guam 1969 only - Jun 22 2:00 1:00 D
+Rule Guam 1969 only - Aug 31 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-70-10-Guam-Daylight-Saving-Time.pdf
+# http://documents.guam.gov/wp-content/uploads/E.O.-70-30-End-of-Guam-Daylight-Saving-Time.pdf
+# http://documents.guam.gov/wp-content/uploads/E.O.-71-5-Guam-Daylight-Savings-Time.pdf
+Rule Guam 1970 1971 - Apr lastSun 2:00 1:00 D
+Rule Guam 1970 1971 - Sep Sun>=1 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-73-28.-Guam-Day-light-Saving-Time.pdf
+Rule Guam 1973 only - Dec 16 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-74-7-Guam-Daylight-Savings-Time-Rescinded.pdf
+Rule Guam 1974 only - Feb 24 2:00 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-76-13-Daylight-Savings-Time.pdf
+Rule Guam 1976 only - May 26 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-76-25-Revocation-of-E.O.-76-13.pdf
+Rule Guam 1976 only - Aug 22 2:01 0 S
+# http://documents.guam.gov/wp-content/uploads/E.O.-77-4-Daylight-Savings-Time.pdf
+Rule Guam 1977 only - Apr 24 2:00 1:00 D
+# http://documents.guam.gov/wp-content/uploads/E.O.-77-18-Guam-Standard-Time.pdf
+Rule Guam 1977 only - Aug 28 2:00 0 S
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Guam -14:21:00 - LMT 1844 Dec 31
9:39:00 - LMT 1901 # Agana
- 10:00 - GST 2000 Dec 23 # Guam
+ 10:00 - GST 1941 Dec 10 # Guam
+ 9:00 - +09 1944 Jul 31
+ 10:00 Guam G%sT 2000 Dec 23
10:00 - ChST # Chamorro Standard Time
Link Pacific/Guam Pacific/Saipan # N Mariana Is
@@ -448,31 +482,56 @@
# Marshall Is
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Majuro 11:24:48 - LMT 1901
- 11:00 - +11 1969 Oct
- 12:00 - +12
-Zone Pacific/Kwajalein 11:09:20 - LMT 1901
- 11:00 - +11 1969 Oct
- -12:00 - -12 1993 Aug 20
- 12:00 - +12
+Zone Pacific/Majuro 11:24:48 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1944 Jan 30
+ 11:00 - +11 1969 Oct
+ 12:00 - +12
+Zone Pacific/Kwajalein 11:09:20 - LMT 1901
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1944 Feb 6
+ 11:00 - +11 1969 Oct
+ -12:00 - -12 1993 Aug 20 24:00
+ 12:00 - +12
# Micronesia
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Chuuk 10:07:08 - LMT 1901
- 10:00 - +10
-Zone Pacific/Pohnpei 10:32:52 - LMT 1901 # Kolonia
- 11:00 - +11
-Zone Pacific/Kosrae 10:51:56 - LMT 1901
- 11:00 - +11 1969 Oct
- 12:00 - +12 1999
- 11:00 - +11
+Zone Pacific/Chuuk -13:52:52 - LMT 1844 Dec 31
+ 10:07:08 - LMT 1901
+ 10:00 - +10 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 10:00 - +10
+Zone Pacific/Pohnpei -13:27:08 - LMT 1844 Dec 31 # Kolonia
+ 10:32:52 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 11:00 - +11
+Zone Pacific/Kosrae -13:08:04 - LMT 1844 Dec 31
+ 10:51:56 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 11:00 - +11 1969 Oct
+ 12:00 - +12 1999
+ 11:00 - +11
# Nauru
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Nauru 11:07:40 - LMT 1921 Jan 15 # Uaobe
- 11:30 - +1130 1942 Mar 15
- 9:00 - +09 1944 Aug 15
- 11:30 - +1130 1979 May
+ 11:30 - +1130 1942 Aug 29
+ 9:00 - +09 1945 Sep 8
+ 11:30 - +1130 1979 Feb 10 2:00
12:00 - +12
# New Caledonia
@@ -573,8 +632,9 @@
# Palau (Belau)
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Palau 8:57:56 - LMT 1901 # Koror
- 9:00 - +09
+Zone Pacific/Palau -15:02:04 - LMT 1844 Dec 31 # Koror
+ 8:57:56 - LMT 1901
+ 9:00 - +09
# Papua New Guinea
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -836,7 +896,7 @@
# tz@iana.org for general use in the future). For more, please see
# the file CONTRIBUTING in the tz distribution.
-# From Paul Eggert (2017-02-10):
+# From Paul Eggert (2018-11-18):
#
# Unless otherwise specified, the source for data through 1990 is:
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -861,6 +921,7 @@
# A reliable and entertaining source about time zones is
# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
#
+# I invented the abbreviation marked "*".
# The following abbreviations are from other sources.
# Corrections are welcome!
# std dst
@@ -868,7 +929,7 @@
# 8:00 AWST AWDT Western Australia
# 9:30 ACST ACDT Central Australia
# 10:00 AEST AEDT Eastern Australia
-# 10:00 GST Guam through 2000
+# 10:00 GST GDT* Guam through 2000
# 10:00 ChST Chamorro
# 11:30 NZMT NZST New Zealand through 1945
# 12:00 NZST NZDT New Zealand 1946-present
@@ -1567,28 +1628,70 @@
# Kwajalein
-# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
-# I wonder what happened in Kwajalein, where there was NO Friday,
-# 1993-08-20. Thursday night at midnight Kwajalein switched sides with
-# respect to the International Date Line, to rejoin its fellow islands,
-# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
+# From an AP article (1993-08-22):
+# "The nearly 3,000 Americans living on this remote Pacific atoll have a good
+# excuse for not remembering Saturday night: there wasn't one. Residents were
+# going to bed Friday night and waking up Sunday morning because at midnight
+# -- 8 A.M. Eastern daylight time on Saturday -- Kwajalein was jumping from
+# one side of the international date line to the other."
+# "In Marshall Islands, Friday is followed by Sunday", NY Times. 1993-08-22.
+# https://www.nytimes.com/1993/08/22/world/in-marshall-islands-friday-is-followed-by-sunday.html
+
+# From Phake Nick (2018-10-27):
+# <https://wiki.suikawiki.org/n/南洋群島の標準時> ... pointed out that
+# currently tzdata say Pacific/Kwajalein switched from GMT+11 to GMT-12 in
+# 1969 October without explanation, however an 1993 article from NYT say it
+# synchorized its day with US mainland about 40 years ago and thus the switch
+# should occur at around 1950s instead.
+#
+# From Paul Eggert (2018-11-18):
+# The NYT (actually, AP) article is vague and possibly wrong about this.
+# The article says the earlier switch was "40 years ago when the United States
+# Army established a missile test range here". However, the Kwajalein Test
+# Center was established on 1960-10-01 and was run by the US Navy. It was
+# transferred to the US Army on 1964-07-01. See "Seize the High Ground"
+# <https://history.army.mil/html/books/070/70-88-1/cmhPub_70-88-1.pdf>.
+# Given that Shanks was right on the money about the 1993 change, I'm inclined
+# to take Shanks's word for the 1969 change unless we find better evidence.
# N Mariana Is, Guam
+# From Phake Nick (2018-10-27):
+# Guam Island was briefly annexed by Japan during ... year 1941-1944 ...
+# however there are no detailed information about what time it use during that
+# period. It would probably be reasonable to assume Guam use GMT+9 during
+# that period of time like the surrounding area.
+
+# From Paul Eggert (2018-11-18):
# Howse writes (p 153) "The Spaniards, on the other hand, reached the
# Philippines and the Ladrones from America," and implies that the Ladrones
# (now called the Marianas) kept American date for quite some time.
# For now, we assume the Ladrones switched at the same time as the Philippines;
# see Asia/Manila.
-
+#
+# Use 1941-12-10 and 1944-07-31 for Guam WWII transitions, as the rough start
+# and end of Japanese control of Agana. We don't know whether the Northern
+# Marianas followed Guam's DST rules from 1959 through 1977; for now, assume
+# they did as that avoids the need for a separate zone due to our 1970 cutoff.
+#
# US Public Law 106-564 (2000-12-23) made UT +10 the official standard time,
# under the name "Chamorro Standard Time". There is no official abbreviation,
# but Congressman Robert A. Underwood, author of the bill that became law,
# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
+# See also the commentary for Micronesia.
-# Micronesia
+
+# Marshall Is
+# See the commentary for Micronesia.
+
+
+# Micronesia (and nearby)
+
+# From Paul Eggert (2018-11-18):
+# Like the Ladrones (see Guam commentary), assume the Spanish East Indies
+# kept American time until the Philippines switched at the end of 1844.
# Alan Eugene Davis writes (1996-03-16),
# "I am certain, having lived there for the past decade, that 'Truk'
@@ -1604,6 +1707,95 @@
# that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
# We don't know when Kosrae switched from +12; assume January 1 for now.
+# From Phake Nick (2018-10-27):
+#
+# From a Japanese wiki site https://wiki.suikawiki.org/n/南洋群島の標準時
+# ...
+# For "Southern Islands" (modern region of Mariana + Palau + Federation of
+# Micronesia + Marshall Islands):
+#
+# A 1906 Japanese magazine shown the Caroline Islands and Mariana Islands
+# who was occupied by Germany at the time as GMT+10, together with the like
+# of German New Guinea. However there is a marking saying it have not been
+# implemented (yet). No further information after that were found.
+#
+# Japan invaded those islands in 1914, and records shows that they were
+# instructed to use JST at the time.
+#
+# 1915 January telecommunication record on the Jaluit Atoll shows they use
+# the meridian of 170E as standard time (GMT+11:20), which is similar to the
+# longitude of the atoll.
+# 1915 February record say the 170E standard time is to be used until
+# February 9 noon, and after February 9 noon they are to use JST.
+# However these are time used within the Japanese Military at the time and
+# probably does not reflect the time used by local resident at the time (that
+# is if they keep their own time back then)
+#
+# In January 1919 the occupying force issued a command that split the area
+# into three different timezone with meridian of 135E, 150E, 165E (JST+0, +1,
+# +2), and the command was to become effective from February 1 of the same
+# year. Despite the target of the command is still only for the occupying
+# force itself, further publication have described the time as the standard
+# time for the occupied area and thus it can probably be seen as such.
+# * Area that use meridian of 135E: Palau and Yap civil administration area
+# (Southern Islands Western Standard Time)
+# * Area that use meridian of 150E: Truk (Chuuk) and Saipan civil
+# administration area (Southern Islands Central Standard Time)
+# * Area that use meridian of 165E: Ponape (Pohnpei) and Jaluit civil
+# administration area (Southern Islands Eastern Standard Time).
+# * In the next few years Japanese occupation of those islands have been
+# formalized via League of Nation Mandate (South Pacific Mandate) and formal
+# governance structure have been established, these district [become
+# subprefectures] and timezone classification have been inherited as standard
+# time of the area.
+# * Saipan subprefecture include Mariana islands (exclude Guam which was
+# occupied by America at the time), Palau and Yap subprefecture rule the
+# Western Caroline Islands with 137E longitude as border, Truk and Ponape
+# subprefecture rule the Eastern Caroline Islands with 154E as border, Ponape
+# subprefecture also rule part of Marshall Islands to the west of 164E
+# starting from (1918?) and Jaluit subprefecture rule the rest of the
+# Marshall Islands.
+#
+# And then in year 1937, an announcement was made to change the time in the
+# area into 2 timezones:
+# * Area that use meridian of 135E: area administered by Palau, Yap and
+# Saipan subprefecture (Southern Islands Western Standard Time)
+# * Area that use meridian of 150E: area administered by Truk (Chuuk),
+# Ponape (Pohnpei) and Jaluit subprefecture (Southern Islands Eastern
+# Standard Time)
+#
+# Another announcement issued in 1941 say that on April 1 that year,
+# standard time of the Southern Islands would be changed to use the meridian
+# of 135E (GMT+9), and thus abolishing timezone different within the area.
+#
+# Then Pacific theater of WWII started and Japan slowly lose control on the
+# island. The webpage I linked above contain no information during this
+# period of time....
+#
+# After the end of WWII, in 1946 February, a document written by the
+# (former?) Japanese military personnel describe there are 3 hours time
+# different between Caroline islands time/Wake island time and the Chungking
+# time, which would mean the time being used there at the time was GMT+10.
+#
+# After that, the area become Trust Territories of the Pacific Islands
+# under American administration from year 1947. The site listed some
+# American/International books/maps/publications about time used in those
+# area during this period of time but they doesn't seems to be reliable
+# information so it would be the best if someone know where can more reliable
+# information can be found.
+#
+#
+# From Paul Eggert (2018-11-18):
+#
+# For the above, use vague dates like "1914" and "1945" for transitions that
+# plausibly exist but for which the details are not known. The information
+# for Wake is too sketchy to act on.
+#
+# The 1906 GMT+10 info about German-controlled islands might not have been
+# done, so omit it from the data for now.
+#
+# The Jaluit info governs Kwajalein.
+
# Midway
@@ -1621,6 +1813,29 @@
# started DST on June 3. Possibly DST was observed other years
# in Midway, but we have no record of it.
+# Nauru
+
+# From Phake Nick (2018-10-31):
+# Currently, the tz database say Nauru use LMT until 1921, and then
+# switched to GMT+11:30 for the next two decades.
+# However, a number of timezone map published in America/Japan back then
+# showed its timezone as GMT+11 per https://wiki.suikawiki.org/n/ナウルの標準時
+# And it would also be nice if the 1921 transition date could be sourced.
+# ...
+# The "Nauru Standard Time Act 1978 Time Change"
+# http://ronlaw.gov.nr/nauru_lpms/files/gazettes/4b23a17d2030150404db7a5fa5872f52.pdf#page=3
+# based on "Nauru Standard Time Act 1978 Time Change"
+# http://www.paclii.org/nr/legis/num_act/nsta1978207/ defined that "Nauru
+# Alternative Time" (GMT+12) should be in effect from 1979 Feb.
+#
+# From Paul Eggert (2018-11-19):
+# The 1921-01-15 introduction of standard time is in Shanks; it is also in
+# "Standard Time Throughout the World", US National Bureau of Standards (1935),
+# page 3, which does not give the UT offset. In response to a comment by
+# Phake Nick I set the Nauru time of occupation by Japan to
+# 1942-08-29/1945-09-08 by using dates from:
+# https://en.wikipedia.org/wiki/Japanese_occupation_of_Nauru
+
# Norfolk
# From Alexander Krivenyshev (2015-09-23):
@@ -1636,6 +1851,9 @@
# other than in 1974/5. See:
# https://www.timeanddate.com/time/australia/norfolk-island.html
+# Palau
+# See commentary for Micronesia.
+
# Pitcairn
# From Rives McDow (1999-11-08):
@@ -1800,6 +2018,9 @@
# From Paul Eggert (2003-03-23):
# We have no other report of DST in Wake Island, so omit this info for now.
+# See also the commentary for Micronesia.
+
+
###############################################################################
# The International Date Line
--- a/test/jdk/sun/util/calendar/zi/tzdata/backward Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/backward Mon Jul 22 11:08:27 2019 +0530
@@ -98,6 +98,7 @@
Link America/Havana Cuba
Link Africa/Cairo Egypt
Link Europe/Dublin Eire
+Link Etc/UTC Etc/UCT
Link Europe/London Europe/Belfast
Link Europe/Chisinau Europe/Tiraspol
Link Europe/London GB
@@ -132,7 +133,7 @@
Link Asia/Seoul ROK
Link Asia/Singapore Singapore
Link Europe/Istanbul Turkey
-Link Etc/UCT UCT
+Link Etc/UTC UCT
Link America/Anchorage US/Alaska
Link America/Adak US/Aleutian
Link America/Phoenix US/Arizona
--- a/test/jdk/sun/util/calendar/zi/tzdata/etcetera Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/etcetera Mon Jul 22 11:08:27 2019 +0530
@@ -40,7 +40,6 @@
Zone Etc/GMT 0 - GMT
Zone Etc/UTC 0 - UTC
-Zone Etc/UCT 0 - UCT
# The following link uses older naming conventions,
# but it belongs here, not in the file 'backward',
--- a/test/jdk/sun/util/calendar/zi/tzdata/europe Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/europe Mon Jul 22 11:08:27 2019 +0530
@@ -1876,7 +1876,7 @@
1:00 Belgium CE%sT 1977
1:00 EU CE%sT
-# Macedonia
+# North Macedonia
# See Europe/Belgrade.
# Malta
@@ -3380,7 +3380,7 @@
Link Europe/Belgrade Europe/Ljubljana # Slovenia
Link Europe/Belgrade Europe/Podgorica # Montenegro
Link Europe/Belgrade Europe/Sarajevo # Bosnia and Herzegovina
-Link Europe/Belgrade Europe/Skopje # Macedonia
+Link Europe/Belgrade Europe/Skopje # North Macedonia
Link Europe/Belgrade Europe/Zagreb # Croatia
# Slovakia
--- a/test/jdk/sun/util/calendar/zi/tzdata/iso3166.tab Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/iso3166.tab Mon Jul 22 11:08:27 2019 +0530
@@ -30,8 +30,8 @@
# All text uses UTF-8 encoding. The columns of the table are as follows:
#
# 1. ISO 3166-1 alpha-2 country code, current as of
-# ISO 3166-1 N905 (2016-11-15). See: Updates on ISO 3166-1
-# http://isotc.iso.org/livelink/livelink/Open/16944257
+# ISO 3166-1 N976 (2018-11-06). See: Updates on ISO 3166-1
+# https://isotc.iso.org/livelink/livelink/Open/16944257
# 2. The usual English name for the coded region,
# chosen so that alphabetic sorting of subsets produces helpful lists.
# This is not the same as the English name in the ISO 3166 tables.
@@ -187,7 +187,7 @@
MF St Martin (French)
MG Madagascar
MH Marshall Islands
-MK Macedonia
+MK North Macedonia
ML Mali
MM Myanmar (Burma)
MN Mongolia
@@ -256,7 +256,7 @@
SV El Salvador
SX St Maarten (Dutch)
SY Syria
-SZ Swaziland
+SZ Eswatini (Swaziland)
TC Turks & Caicos Is
TD Chad
TF French Southern & Antarctic Lands
--- a/test/jdk/sun/util/calendar/zi/tzdata/leapseconds Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/leapseconds Mon Jul 22 11:08:27 2019 +0530
@@ -40,9 +40,12 @@
# See: Levine J. Coordinated Universal Time and the leap second.
# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995
# <https://ieeexplore.ieee.org/document/7909995>.
+
# There were no leap seconds before 1972, because the official mechanism
# accounting for the discrepancy between atomic time and the earth's rotation
-# did not exist.
+# did not exist. The first ("1 Jan 1972") data line in leap-seconds.list
+# does not denote a leap second; it denotes the start of the current definition
+# of UTC.
# The correction (+ or -) is made at the given time, so lines
# will typically look like:
@@ -81,7 +84,7 @@
# POSIX timestamps for the data in this file:
#updated 1467936000
-#expires 1561680000
+#expires 1577491200
-# Updated through IERS Bulletin C56
-# File expires on: 28 June 2019
+# Updated through IERS Bulletin C57
+# File expires on: 28 December 2019
--- a/test/jdk/sun/util/calendar/zi/tzdata/northamerica Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/northamerica Mon Jul 22 11:08:27 2019 +0530
@@ -620,6 +620,26 @@
# between AKST and AKDT from now on....
# https://www.krbd.org/2015/10/30/annette-island-times-they-are-a-changing/
+# From Ryan Stanley (2018-11-06):
+# The Metlakatla community in Alaska has decided not to change its
+# clock back an hour starting on November 4th, 2018 (day before yesterday).
+# They will be gmtoff=-28800 year-round.
+# https://www.facebook.com/141055983004923/photos/pb.141055983004923.-2207520000.1541465673./569081370202380/
+
+# From Paul Eggert (2018-12-16):
+# In a 2018-12-11 special election, Metlakatla voted to go back to
+# Alaska time (including daylight saving time) starting next year.
+# https://www.krbd.org/2018/12/12/metlakatla-to-follow-alaska-standard-time-allow-liquor-sales/
+#
+# From Ryan Stanley (2019-01-11):
+# The community will be changing back on the 20th of this month...
+# From Tim Parenti (2019-01-11):
+# Per an announcement on the Metlakatla community's official Facebook page, the
+# "fall back" will be on Sunday 2019-01-20 at 02:00:
+# https://www.facebook.com/141055983004923/photos/607150969728753/
+# So they won't be waiting for Alaska to join them on 2019-03-10, but will
+# rather change their clocks twice in seven weeks.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32
-8:57:41 - LMT 1900 Aug 20 12:00
@@ -646,6 +666,8 @@
-8:00 - PST 1969
-8:00 US P%sT 1983 Oct 30 2:00
-8:00 - PST 2015 Nov 1 2:00
+ -9:00 US AK%sT 2018 Nov 4 2:00
+ -8:00 - PST 2019 Jan 20 2:00
-9:00 US AK%sT
Zone America/Yakutat 14:41:05 - LMT 1867 Oct 19 15:12:18
-9:18:55 - LMT 1900 Aug 20 12:00
@@ -806,6 +828,22 @@
# For a map of Indiana's time zone regions, see:
# https://en.wikipedia.org/wiki/Time_in_Indiana
#
+# From Paul Eggert (2018-11-30):
+# A brief but entertaining history of time in Indiana describes a 1949 debate
+# in the Indiana House where city legislators (who favored "fast time")
+# tussled with farm legislators (who didn't) over a bill to outlaw DST:
+# "Lacking enough votes, the city faction tries to filibuster until time runs
+# out on the session at midnight, but rural champion Rep. Herbert Copeland,
+# R-Madison, leans over the gallery railing and forces the official clock
+# back to 9 p.m., breaking it in the process. The clock sticks on 9 as the
+# debate rages on into the night. The filibuster finally dies out and the
+# bill passes, while outside the chamber, clocks read 3:30 a.m. In the end,
+# it doesn't matter which side won. The law has no enforcement powers and
+# is simply ignored by fast-time communities."
+# How Indiana went from 'God's time' to split zones and daylight-saving.
+# Indianapolis Star. 2018-11-27 14:58 -05.
+# https://www.indystar.com/story/news/politics/2018/11/27/indianapolis-indiana-time-zone-history-central-eastern-daylight-savings-time/2126300002/
+#
# From Paul Eggert (2007-08-17):
# Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
# with the following exceptions:
--- a/test/jdk/sun/util/calendar/zi/tzdata/zone.tab Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jdk/sun/util/calendar/zi/tzdata/zone.tab Mon Jul 22 11:08:27 2019 +0530
@@ -260,6 +260,7 @@
KY +1918-08123 America/Cayman
KZ +4315+07657 Asia/Almaty Kazakhstan (most areas)
KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda
+KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay
KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe
KZ +4431+05016 Asia/Aqtau Mangghystau/Mankistau
KZ +4707+05156 Asia/Atyrau Atyrau/Atirau/Gur'yev
@@ -353,9 +354,9 @@
RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad
RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area
RU +4457+03406 Europe/Simferopol MSK+00 - Crimea
-RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd
RU +5836+04939 Europe/Kirov MSK+00 - Kirov
RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan
+RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd
RU +5134+04602 Europe/Saratov MSK+01 - Saratov
RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk
RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia
--- a/test/jtreg-ext/requires/VMProps.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/jtreg-ext/requires/VMProps.java Mon Jul 22 11:08:27 2019 +0530
@@ -455,7 +455,7 @@
}
private boolean checkDockerSupport() throws IOException, InterruptedException {
- ProcessBuilder pb = new ProcessBuilder("docker", "ps");
+ ProcessBuilder pb = new ProcessBuilder(Platform.DOCKER_COMMAND, "ps");
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/TextBlockIllegalEscape.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8227640
+ * @summary Verify that illegal escapes in text blocks do not crash the javac.
+ * @compile/fail/ref=TextBlockIllegalEscape.out --enable-preview -source ${jdk.version} -XDrawDiagnostics TextBlockIllegalEscape.java
+ */
+
+public class TextBlockIllegalEscape {
+ static void test() {
+ EQ("""
+ \!
+ """, "");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/TextBlockIllegalEscape.out Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,4 @@
+TextBlockIllegalEscape.java:11:13: compiler.err.illegal.esc.char
+- compiler.note.preview.filename: TextBlockIllegalEscape.java
+- compiler.note.preview.recompile
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/api/TestGetScopeBinaryNames.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8223443
+ * @summary Verify binary names are not changed and are correct
+ * when using Trees.getScope
+ * @modules jdk.compiler
+ */
+
+import com.sun.source.tree.ClassTree;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.NestingKind;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.tools.JavaCompiler;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Scope;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.Tree.Kind;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+
+import static javax.tools.JavaFileObject.Kind.SOURCE;
+
+public class TestGetScopeBinaryNames {
+ public static void main(String... args) throws IOException {
+ new TestGetScopeBinaryNames().run();
+ }
+
+ public void run() throws IOException {
+ class EnclosingDesc {
+ final String code;
+ final boolean supportsLocal;
+ public EnclosingDesc(String code, boolean supportsLocal) {
+ this.code = code;
+ this.supportsLocal = supportsLocal;
+ }
+ }
+ List<EnclosingDesc> enclosingEnvs = List.of(
+ new EnclosingDesc("class Test {" +
+ " void test() {" +
+ " $" +
+ " }" +
+ "}",
+ true),
+ new EnclosingDesc("class Test {" +
+ " {" +
+ " $" +
+ " }" +
+ "}",
+ true),
+ new EnclosingDesc("class Test {" +
+ " static {" +
+ " $" +
+ " }" +
+ "}",
+ true),
+ new EnclosingDesc("class Test {" +
+ " Object I = $" +
+ "}",
+ true)
+ );
+ class LocalDesc {
+ final String localCode;
+ final boolean isLocalClass;
+ public LocalDesc(String localCode, boolean isLocalClass) {
+ this.localCode = localCode;
+ this.isLocalClass = isLocalClass;
+ }
+ }
+ List<LocalDesc> locals = List.of(
+ new LocalDesc("new A() {" +
+ " class AI extends B {" +
+ " class AII extends C {" +
+ " private void t() {" +
+ " new D() { class DI extends E {} };" +
+ " }" +
+ " }" +
+ " private void t() { new F() {}; }" +
+ " }" +
+ " private void t() { new G() {}; }" +
+ "};",
+ false),
+ new LocalDesc("class AA extends A {" +
+ " class AI extends B {" +
+ " class AII extends C {" +
+ " private void t() {" +
+ " new D() { class DI extends E {} };" +
+ " }" +
+ " }" +
+ " private void t() { new F() {}; }" +
+ " }" +
+ " private void t() { new G() {}; }" +
+ "}",
+ false)
+ );
+ String markerClasses = "class A {} class B {} class C {}" +
+ "class D {} class E {} class F {}" +
+ "class G {}";
+ for (EnclosingDesc enclosing : enclosingEnvs) {
+ for (LocalDesc local : locals) {
+ if (!local.isLocalClass || enclosing.supportsLocal) {
+ doTest(enclosing.code.replace("$", local.localCode) +
+ markerClasses);
+ }
+ }
+ }
+ }
+
+ void doTest(String code, String... expected) throws IOException {
+ Map<String, String> name2BinaryName = new HashMap<>();
+ Map<String, String> name2QualifiedName = new HashMap<>();
+
+ computeNames(code, name2BinaryName, name2QualifiedName);
+
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ JavacTask t = (JavacTask) c.getTask(null, null, null, null, null,
+ List.of(new MyFileObject(code)));
+ CompilationUnitTree cut = t.parse().iterator().next();
+ Trees trees = Trees.instance(t);
+
+ t.addTaskListener(new TaskListener() {
+ @Override
+ public void finished(TaskEvent e) {
+ if (e.getKind() == TaskEvent.Kind.ENTER) {
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void scan(Tree tree, Void p) {
+ if (tree != null &&
+ !isInExtendsClause(getCurrentPath(), tree)) {
+ TreePath path =
+ new TreePath(getCurrentPath(), tree);
+ Scope scope = trees.getScope(path);
+ checkScope(t.getElements(), scope,
+ name2BinaryName, name2QualifiedName);
+ }
+ return super.scan(tree, p);
+ }
+ }.scan(cut, null);
+ }
+ }
+ });
+
+ t.analyze();
+
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void visitClass(ClassTree node, Void p) {
+ TypeElement type =
+ (TypeElement) trees.getElement(getCurrentPath());
+ checkClass(t.getElements(), type,
+ name2BinaryName, name2QualifiedName);
+ return super.visitClass(node, p);
+ }
+ }.scan(cut, null);
+
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void scan(Tree tree, Void p) {
+ if (tree != null &&
+ !isInExtendsClause(getCurrentPath(), tree)) {
+ TreePath path =
+ new TreePath(getCurrentPath(), tree);
+ Scope scope = trees.getScope(path);
+ checkScope(t.getElements(), scope,
+ name2BinaryName, name2QualifiedName);
+ }
+ return super.scan(tree, p);
+ }
+ }.scan(cut, null);
+ }
+
+ void computeNames(String code,
+ Map<String, String> name2BinaryName,
+ Map<String, String> name2QualifiedName) throws IOException {
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ JavacTask t = (JavacTask) c.getTask(null, null, null, null, null,
+ List.of(new MyFileObject(code)));
+ CompilationUnitTree cut = t.parse().iterator().next();
+
+ t.analyze();
+
+ new TreePathScanner<Void, Void>() {
+ Trees trees = Trees.instance(t);
+ Elements els = t.getElements();
+ @Override
+ public Void visitClass(ClassTree node, Void p) {
+ TypeElement type =
+ (TypeElement) trees.getElement(getCurrentPath());
+ String key = type.getSuperclass().toString();
+
+ name2BinaryName.put(key, els.getBinaryName(type).toString());
+ name2QualifiedName.put(key, type.getQualifiedName().toString());
+ return super.visitClass(node, p);
+ }
+ }.scan(cut, null);
+ }
+
+ boolean isInExtendsClause(TreePath clazz, Tree toCheck) {
+ return clazz != null &&
+ clazz.getLeaf().getKind() == Kind.CLASS &&
+ ((ClassTree) clazz.getLeaf()).getExtendsClause() == toCheck;
+ }
+
+ void checkClass(Elements els, TypeElement type,
+ Map<String, String> name2BinaryName,
+ Map<String, String> name2QualifiedName) {
+ if (type.getNestingKind() == NestingKind.TOP_LEVEL ||
+ type.getNestingKind() == NestingKind.MEMBER) {
+ return ;
+ }
+
+ String binaryName = name2BinaryName.get(type.getSuperclass().toString());
+
+ if (!els.getBinaryName(type).contentEquals(binaryName)) {
+ throw new AssertionError("Unexpected: " + els.getBinaryName(type));
+ }
+
+ String qualifiedName = name2QualifiedName.get(type.getSuperclass().toString());
+
+ if (qualifiedName != null) {
+ if (!type.getQualifiedName().contentEquals(qualifiedName)) {
+ throw new AssertionError("Unexpected: " + type.getQualifiedName() +
+ ", expected: " + qualifiedName);
+ }
+ }
+ }
+
+ void checkScope(Elements els, Scope scope,
+ Map<String, String> name2BinaryName,
+ Map<String, String> name2QualifiedName) {
+ while (scope != null) {
+ for (Element el : scope.getLocalElements()) {
+ if (el.getKind().isClass()) {
+ checkClass(els, (TypeElement) el,
+ name2BinaryName, name2QualifiedName);
+ }
+ }
+ scope = scope.getEnclosingScope();
+ }
+ }
+
+ class MyFileObject extends SimpleJavaFileObject {
+ private final String code;
+
+ MyFileObject(String code) {
+ super(URI.create("myfo:///Test.java"), SOURCE);
+ this.code = code;
+ }
+ @Override
+ public String getCharContent(boolean ignoreEncodingErrors) {
+ return code;
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/api/TestGetScopeErrors.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8223443
+ * @summary Verify errors are not reported when computing Scopes.
+ * @modules jdk.compiler
+ */
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import static javax.tools.JavaFileObject.Kind.SOURCE;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+
+public class TestGetScopeErrors {
+ public static void main(String... args) throws IOException {
+ new TestGetScopeErrors().run();
+ }
+
+ void run() throws IOException {
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ String code =
+ "public class Test {" +
+ " private Object obj = new Object() {" +
+ " private Unresolvable u;" +
+ " };" +
+ " void test() {" +
+ " new Object() {" +
+ " private Unresolvable u;" +
+ " };" +
+ " }" +
+ "}";
+ class MyFileObject extends SimpleJavaFileObject {
+ MyFileObject() {
+ super(URI.create("myfo:///Test.java"), SOURCE);
+ }
+ @Override
+ public String getCharContent(boolean ignoreEncodingErrors) {
+ return code;
+ }
+ }
+ AtomicBoolean enterDone = new AtomicBoolean();
+ List<String> errors = new ArrayList<>();
+ DiagnosticListener<JavaFileObject> noErrors = d -> {
+ if (!enterDone.get() && d.getKind() == Diagnostic.Kind.ERROR) {
+ throw new AssertionError(d.toString());
+ }
+ errors.add(d.getSource().getName() + ":" +
+ d.getPosition() + ":" +
+ d.getCode());
+ };
+ JavacTask t =
+ (JavacTask) c.getTask(null, null, noErrors,
+ Arrays.asList("-XDrawDiagnostics"),
+ null, List.of(new MyFileObject()));
+ CompilationUnitTree cut = t.parse().iterator().next();
+ Trees trees = Trees.instance(t);
+ t.addTaskListener(new TaskListener() {
+ @Override
+ public void finished(TaskEvent e) {
+ if (e.getKind() == TaskEvent.Kind.ENTER) {
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void scan(Tree tree, Void p) {
+ if (tree != null) {
+ TreePath path =
+ new TreePath(getCurrentPath(), tree);
+ trees.getScope(path);
+ }
+ return super.scan(tree, p);
+ }
+ }.scan(cut, null);
+ enterDone.set(true);
+ }
+ }
+ });
+
+ t.analyze();
+
+ List<String> expectedErrors = List.of(
+ "/Test.java:74:compiler.err.cant.resolve",
+ "/Test.java:154:compiler.err.cant.resolve"
+ );
+
+ if (!expectedErrors.equals(errors)) {
+ throw new IllegalStateException("Unexpected errors: " + errors);
+ }
+ }
+
+}
--- a/test/langtools/tools/javac/file/LimitedImage.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/javac/file/LimitedImage.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
- * @run main/othervm --limit-modules jdk.compiler LimitedImage
+ * @run main/othervm --limit-modules jdk.compiler,jdk.internal.vm.compiler LimitedImage
*/
import java.io.IOException;
--- a/test/langtools/tools/javac/modules/InheritRuntimeEnvironmentTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/javac/modules/InheritRuntimeEnvironmentTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -130,7 +130,8 @@
// This is the test, to verify that the module being compiled will not be able to read
// modules on the module path when a --limit-modules is used
new TestCase(base)
- .testOpts("--module-path", modules.toString(), "--limit-modules", "jdk.compiler")
+ .testOpts("--module-path", modules.toString(),
+ "--limit-modules", "jdk.compiler,jdk.internal.vm.compiler")
.otherOpts("-XDrawDiagnostics",
"--module-source-path", src.toString(),
"-classpath", emptyClassPath.toString())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/recovery/LocalVarHiding.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8227010
+ * @summary Verify error recovery after variable redeclaration
+ * @compile/fail/ref=LocalVarHiding.out -XDrawDiagnostics LocalVarHiding.java
+ */
+
+public class LocalVarHiding {
+ public void test(Decl l1) {
+ System.err.println(l1.originalMethod());
+
+ OverrideVar l1 = new OverrideVar();
+
+ System.err.println(l1.overrideMethod());
+
+ Decl l2 = new Decl();
+
+ System.err.println(l2.originalMethod());
+
+ OverrideVar l2 = new OverrideVar();
+
+ System.err.println(l2.overrideMethod());
+
+ Decl l3 = new Decl();
+
+ System.err.println(l3.originalMethod());
+
+ {
+ OverrideVar l3 = new OverrideVar();
+
+ System.err.println(l3.overrideMethod());
+ }
+
+ Decl l4 = new Decl();
+
+ System.err.println(l4.originalMethod());
+
+ try {
+ throw new OverrideVar();
+ } catch (OverrideVar l4) {
+ System.err.println(l4.overrideMethod());
+ }
+
+ Decl l5 = new Decl();
+
+ System.err.println(l5.originalMethod());
+
+ try (OverrideVar l5 = null) {
+ System.err.println(l5.overrideMethod());
+ }
+
+ Decl l6 = new Decl();
+
+ System.err.println(l6.originalMethod());
+
+ I i1 = l6 -> {
+ System.err.println(l6.overrideMethod());
+ };
+ I i2 = (OverrideVar l6) -> {
+ System.err.println(l6.overrideMethod());
+ };
+ }
+
+ public class Decl {
+ public int originalMethod() {}
+ }
+
+ public class OverrideVar extends Exception implements AutoCloseable {
+ @Override public void close() throws Exception {}
+ public int overrideMethod() {}
+ }
+
+ public interface I {
+ public void run(OverrideVar ov);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/recovery/LocalVarHiding.out Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,8 @@
+LocalVarHiding.java:35:21: compiler.err.already.defined: kindname.variable, l1, kindname.method, test(LocalVarHiding.Decl)
+LocalVarHiding.java:43:21: compiler.err.already.defined: kindname.variable, l2, kindname.method, test(LocalVarHiding.Decl)
+LocalVarHiding.java:52:25: compiler.err.already.defined: kindname.variable, l3, kindname.method, test(LocalVarHiding.Decl)
+LocalVarHiding.java:63:30: compiler.err.already.defined: kindname.variable, l4, kindname.method, test(LocalVarHiding.Decl)
+LocalVarHiding.java:71:26: compiler.err.already.defined: kindname.variable, l5, kindname.method, test(LocalVarHiding.Decl)
+LocalVarHiding.java:79:16: compiler.err.already.defined: kindname.variable, l6, kindname.method, test(LocalVarHiding.Decl)
+LocalVarHiding.java:82:29: compiler.err.already.defined: kindname.variable, l6, kindname.method, test(LocalVarHiding.Decl)
+7 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchexpr/LambdaCapture.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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 8220041
+ * @summary Verify variable capture works inside switch expressions which are
+ * inside variable declarations
+ * @compile --enable-preview -source ${jdk.version} LambdaCapture.java
+ */
+
+import java.util.Objects;
+
+public class LambdaCapture {
+ public static void main(String... args) {
+ new LambdaCapture().run();
+ }
+
+ void run() {
+ assertEquals("00", lambdaCapture1(0).t());
+ assertEquals("12", lambdaCapture1(1).t());
+ assertEquals("D", lambdaCapture1(2).t());
+ assertEquals("D", lambdaCapture1(3).t());
+ assertEquals("00", lambdaCapture2(0).t());
+ assertEquals("12", lambdaCapture2(1).t());
+ assertEquals("D", lambdaCapture2(2).t());
+ assertEquals("D", lambdaCapture2(3).t());
+ }
+
+ I<String> lambdaCapture1(int i) {
+ int j = i + 1;
+ I<String> r = switch (i) {
+ case 0 -> () -> "0" + i; //capture parameter
+ case 1 -> () -> "1" + j; //capture local variable
+ default -> {
+ String k = "D";
+ yield () -> k; //capture local from the switch expr.
+ }
+ };
+
+ return r;
+ }
+
+ I<String> lambdaCapture2(int i) {
+ int j = i + 1;
+
+ return switch (i) {
+ case 0 -> () -> "0" + i; //capture parameter
+ case 1 -> () -> "1" + j; //capture local variable
+ default -> {
+ String k = "D";
+ yield () -> k; //capture local from the switch expr.
+ }
+ };
+ }
+
+ {
+ int j1 = 1;
+ I<String> r1 = switch (j1) {
+ case 1 -> () -> "1" + j1; //capture local variable
+ default -> {
+ String k = "D";
+ yield () -> k; //capture local from the switch expr.
+ }
+ };
+ assertEquals("11", r1.t());
+
+ int j2 = 2;
+ I<String> r2 = switch (j2) {
+ case 1 -> () -> "1" + j2; //capture local variable
+ default -> {
+ String k = "D";
+ yield () -> k; //capture local from the switch expr.
+ }
+ };
+ assertEquals("D", r2.t());
+ }
+
+ private void assertEquals(Object expected, Object actual) {
+ if (!Objects.equals(expected, actual)) {
+ throw new AssertionError("Unexpected value: " + actual);
+ }
+ }
+
+ interface I<T> {
+ public T t();
+ }
+}
--- a/test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8223305
+ * @bug 8223305 8226522
* @summary Verify correct warnings w.r.t. yield
* @compile/ref=WarnWrongYieldTest.out -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=ATTR WarnWrongYieldTest.java
*/
@@ -159,4 +159,12 @@
//OK - yield is a variable:
yield[0] = 5;
}
+
+ private void lambda() {
+ SAM s = (yield y) -> {};
+ }
+
+ interface SAM {
+ public void m(yield o);
+ }
}
--- a/test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.out Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.out Mon Jul 22 11:08:27 2019 +0530
@@ -11,8 +11,11 @@
WarnWrongYieldTest.java:118:9: compiler.warn.invalid.yield
WarnWrongYieldTest.java:123:22: compiler.warn.invalid.yield
WarnWrongYieldTest.java:152:24: compiler.warn.invalid.yield
+WarnWrongYieldTest.java:164:18: compiler.warn.restricted.type.not.allowed.preview: yield, 13
+WarnWrongYieldTest.java:168:23: compiler.warn.restricted.type.not.allowed.preview: yield, 13
WarnWrongYieldTest.java:34:28: compiler.warn.illegal.ref.to.restricted.type: yield
WarnWrongYieldTest.java:45:5: compiler.warn.illegal.ref.to.restricted.type: yield
+WarnWrongYieldTest.java:168:23: compiler.warn.illegal.ref.to.restricted.type: yield
WarnWrongYieldTest.java:72:9: compiler.warn.illegal.ref.to.restricted.type: yield
WarnWrongYieldTest.java:75:9: compiler.warn.illegal.ref.to.restricted.type: yield
WarnWrongYieldTest.java:75:24: compiler.warn.illegal.ref.to.restricted.type: yield
@@ -22,4 +25,5 @@
WarnWrongYieldTest.java:84:27: compiler.warn.illegal.ref.to.restricted.type: yield
WarnWrongYieldTest.java:84:43: compiler.warn.illegal.ref.to.restricted.type: yield
WarnWrongYieldTest.java:153:24: compiler.warn.illegal.ref.to.restricted.type: yield
-24 warnings
+WarnWrongYieldTest.java:164:18: compiler.warn.illegal.ref.to.restricted.type: yield
+28 warnings
\ No newline at end of file
--- a/test/langtools/tools/javac/switchexpr/WrongYieldTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/WrongYieldTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8223305
+ * @bug 8223305 8226522
* @summary Ensure proper errors are returned for yields.
* @compile/fail/ref=WrongYieldTest.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=ATTR WrongYieldTest.java
*/
@@ -222,4 +222,12 @@
//OK - yield is a variable:
yield[0] = 5;
}
+
+ private void lambda() {
+ SAM s = (yield y) -> {};
+ }
+
+ interface SAM {
+ public void m(Object o);
+ }
}
--- a/test/langtools/tools/javac/switchexpr/WrongYieldTest.out Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/WrongYieldTest.out Mon Jul 22 11:08:27 2019 +0530
@@ -1,11 +1,13 @@
WrongYieldTest.java:39:11: compiler.err.restricted.type.not.allowed: yield, 13
WrongYieldTest.java:45:5: compiler.err.restricted.type.not.allowed.here: yield
+WrongYieldTest.java:123:15: compiler.err.restricted.type.not.allowed.here: yield
WrongYieldTest.java:136:9: compiler.err.invalid.yield
WrongYieldTest.java:146:9: compiler.err.invalid.yield
WrongYieldTest.java:151:9: compiler.err.invalid.yield
WrongYieldTest.java:161:9: compiler.err.invalid.yield
WrongYieldTest.java:166:22: compiler.err.invalid.yield
WrongYieldTest.java:215:24: compiler.err.invalid.yield
+WrongYieldTest.java:227:18: compiler.err.restricted.type.not.allowed.here: yield
WrongYieldTest.java:34:24: compiler.err.illegal.ref.to.restricted.type: yield
WrongYieldTest.java:95:9: compiler.err.no.switch.expression
WrongYieldTest.java:95:15: compiler.err.cant.resolve.location: kindname.variable, y1, , , (compiler.misc.location: kindname.class, t.WrongYieldTest, null)
@@ -26,4 +28,4 @@
WrongYieldTest.java:216:24: compiler.err.illegal.ref.to.restricted.type: yield
- compiler.note.preview.filename: WrongYieldTest.java
- compiler.note.preview.recompile
-26 errors
+28 errors
--- a/test/langtools/tools/sjavac/IdleShutdown.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/langtools/tools/sjavac/IdleShutdown.java Mon Jul 22 11:08:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -88,9 +88,13 @@
long error = Math.abs(expectedTimeout - timeoutTimestamp.get());
log("Timeout error: " + error + " ms");
- if (error > TIMEOUT_MS * .1)
- throw new AssertionError("Error too big");
-
+ String timeoutFactorText = System.getProperty("test.timeout.factor", "1.0");
+ double timeoutFactor = Double.parseDouble(timeoutFactorText);
+ double allowedError = TIMEOUT_MS * 0.1 * timeoutFactor;
+ if (error > allowedError) {
+ throw new AssertionError("Timeout error too large, error is " + error +
+ " milliseconds, we allowed " + allowedError + " milliseconds");
+ }
log("Shutting down");
service.shutdown();
}
--- a/test/lib/jdk/test/lib/Platform.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/lib/jdk/test/lib/Platform.java Mon Jul 22 11:08:27 2019 +0530
@@ -33,6 +33,12 @@
import java.security.PrivilegedExceptionAction;
public class Platform {
+ // Use this property to specify docker location on your system.
+ // E.g.: "/usr/local/bin/docker". We define this constant here so
+ // that it can be used in VMProps as well which checks docker support
+ // via this command
+ public static final String DOCKER_COMMAND =
+ System.getProperty("jdk.test.docker.command", "docker");
public static final String vmName = privilegedGetProperty("java.vm.name");
public static final String vmInfo = privilegedGetProperty("java.vm.info");
private static final String osVersion = privilegedGetProperty("os.version");
--- a/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java Mon Jul 22 11:08:27 2019 +0530
@@ -531,16 +531,20 @@
long newUsage = metrics.getCpuUsage();
long[] newPerCpu = metrics.getPerCpuUsage();
- if (newSysVal <= startSysVal) {
+ // system/user CPU usage counters may be slowly increasing.
+ // allow for equal values for a pass
+ if (newSysVal < startSysVal) {
fail(SubSystem.CPU, "getCpuSystemUsage", newSysVal, startSysVal);
}
- if (newUserVal <= startUserVal) {
+ // system/user CPU usage counters may be slowly increasing.
+ // allow for equal values for a pass
+ if (newUserVal < startUserVal) {
fail(SubSystem.CPU, "getCpuUserUsage", newUserVal, startUserVal);
}
if (newUsage <= startUsage) {
- fail(SubSystem.CPU, "getCpuUserUsage", newUsage, startUsage);
+ fail(SubSystem.CPU, "getCpuUsage", newUsage, startUsage);
}
boolean success = false;
--- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java Mon Jul 22 11:08:27 2019 +0530
@@ -37,6 +37,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import jdk.test.lib.Platform;
import jdk.test.lib.Utils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
@@ -54,11 +55,6 @@
// diagnostic information.
private static final int MAX_LINES_TO_COPY_FOR_CHILD_STDOUT = 100;
- // Use this property to specify docker location on your system.
- // E.g.: "/usr/local/bin/docker".
- private static final String DOCKER_COMMAND =
- System.getProperty("jdk.test.docker.command", "docker");
-
// Set this property to true to retain image after test. By default
// images are removed after test execution completes.
// Retaining the image can be useful for diagnostics and image inspection.
@@ -116,7 +112,7 @@
*/
private static boolean isDockerEngineAvailableCheck() throws Exception {
try {
- execute(DOCKER_COMMAND, "ps")
+ execute(Platform.DOCKER_COMMAND, "ps")
.shouldHaveExitValue(0)
.shouldContain("CONTAINER")
.shouldContain("IMAGE");
@@ -179,9 +175,8 @@
DockerfileConfig.getBaseImageVersion());
try {
// Build the docker
- execute(DOCKER_COMMAND, "build", "--no-cache", "--tag", imageName, buildDir.toString())
- .shouldHaveExitValue(0)
- .shouldContain("Successfully built");
+ execute(Platform.DOCKER_COMMAND, "build", "--no-cache", "--tag", imageName, buildDir.toString())
+ .shouldHaveExitValue(0);
} catch (Exception e) {
// If docker image building fails there is a good chance it happens due to environment and/or
// configuration other than product failure. Throw jtreg skipped exception in such case
@@ -202,7 +197,7 @@
public static List<String> buildJavaCommand(DockerRunOptions opts) throws Exception {
List<String> cmd = new ArrayList<>();
- cmd.add(DOCKER_COMMAND);
+ cmd.add(Platform.DOCKER_COMMAND);
cmd.add("run");
if (opts.tty)
cmd.add("--tty=true");
@@ -244,7 +239,7 @@
* @throws Exception
*/
public static void removeDockerImage(String imageNameAndTag) throws Exception {
- execute(DOCKER_COMMAND, "rmi", "--force", imageNameAndTag);
+ execute(Platform.DOCKER_COMMAND, "rmi", "--force", imageNameAndTag);
}
--- a/test/lib/jdk/test/lib/util/FileUtils.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/lib/jdk/test/lib/util/FileUtils.java Mon Jul 22 11:08:27 2019 +0530
@@ -96,7 +96,7 @@
*/
public static void deleteFileIfExistsWithRetry(Path path) throws IOException {
try {
- if (Files.exists(path)) {
+ if (!Files.notExists(path)) {
deleteFileWithRetry0(path);
}
} catch (InterruptedException x) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/NetworkInterfaceLookup.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Assess time to perform native NetworkInterface lookups; uses
+ * reflection to access both package-private isBoundInetAddress and
+ * public getByInetAddress (to get comparable numbers)
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+@Fork(2)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 10, time = 2)
+public class NetworkInterfaceLookup {
+
+ static final InetAddress address = InetAddress.getLoopbackAddress();
+
+ static final Method isBoundInetAddress_method;
+
+ static final Method getByInetAddress_method;
+
+ static {
+ Method isBound = null;
+ Method getByInet = null;
+
+ try {
+ isBound = NetworkInterface.class.getDeclaredMethod("isBoundInetAddress", InetAddress.class);
+ isBound.setAccessible(true);
+ } catch (Exception e) {
+ System.out.println("NetworkInterface.isBoundInetAddress not found");
+ }
+
+ try {
+ getByInet = NetworkInterface.class.getDeclaredMethod("getByInetAddress", InetAddress.class);
+ } catch (Exception e) {
+ System.out.println("NetworkInterface.getByInetAddress not found");
+ }
+ isBoundInetAddress_method = isBound;
+ getByInetAddress_method = getByInet;
+ }
+
+ @Benchmark
+ public boolean bound() throws Exception {
+ return (boolean)isBoundInetAddress_method.invoke(null, address);
+ }
+
+ @Benchmark
+ public NetworkInterface getByInetAddress() throws Exception {
+ return (NetworkInterface)getByInetAddress_method.invoke(null, address);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/TypeVectorOperations.java Mon Jul 22 11:08:27 2019 +0530
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.*;
+
+import java.util.concurrent.TimeUnit;
+import java.util.Random;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public abstract class TypeVectorOperations {
+ @Param({"512","1024", "2048"})
+ public int COUNT;
+
+ private byte[] bytesA;
+ private byte[] bytesB;
+ private byte[] resB;
+ private short[] shorts;
+ private short[] resS;
+ private int[] ints;
+ private int[] resI;
+ private long[] longs;
+ private long[] resL;
+ private double[] doubles;
+ private double[] resD;
+ private float[] floats;
+ private float[] resF;
+
+ @Param("0")
+ private int seed;
+ private Random r = new Random(seed);
+
+ @Setup
+ public void init() {
+ bytesA = new byte[COUNT];
+ bytesB = new byte[COUNT];
+ resB = new byte[COUNT];
+ shorts = new short[COUNT];
+ resS = new short[COUNT];
+ ints = new int[COUNT];
+ resI = new int[COUNT];
+ longs = new long[COUNT];
+ resL = new long[COUNT];
+ doubles = new double[COUNT];
+ resD = new double[COUNT];
+ floats = new float[COUNT];
+ resF = new float[COUNT];
+
+ for (int i = 0; i < COUNT; i++) {
+ shorts[i] = (short) r.nextInt(Short.MAX_VALUE + 1);
+ ints[i] = r.nextInt();
+ longs[i] = r.nextLong();
+ floats[i] = r.nextFloat();
+ doubles[i] = r.nextDouble();
+ }
+
+ r.nextBytes(bytesA);
+ r.nextBytes(bytesB);
+
+ }
+
+ @Benchmark
+ public void absB() {
+ for (int i = 0; i < COUNT; i++) {
+ byte a = bytesA[i];
+ resB[i] = (byte) (Math.abs((byte) a));
+ }
+ }
+
+ @Benchmark
+ public void mulB() {
+ for (int i = 0; i < COUNT; i++) {
+ byte a = bytesA[i];
+ byte b = bytesB[i];
+ resI[i] = a * b;
+ }
+ }
+
+ @Benchmark
+ public void lShiftB() {
+ for (int i = 0; i < COUNT; i++) {
+ resB[i] = (byte) (bytesA[i] << 3);
+ }
+ }
+
+ @Benchmark
+ public void rShiftB() {
+ for (int i = 0; i < COUNT; i++) {
+ resB[i] = (byte) (bytesA[i] >> 3);
+ }
+ }
+
+ @Benchmark
+ public void urShiftB() {
+ for (int i = 0; i < COUNT; i++) {
+ resB[i] = (byte) (bytesA[i] >>> 3);
+ }
+ }
+
+ @Benchmark
+ public void absS() {
+ for (int i = 0; i < COUNT; i++) {
+ short a = shorts[i];
+ resS[i] = (short) (Math.abs((short) a));
+ }
+ }
+
+ @Benchmark
+ public void absI() {
+ for (int i = 0; i < COUNT; i++) {
+ int a = ints[i];
+ resI[i] = Math.abs(a);
+ }
+ }
+
+ @Benchmark
+ public void mulI() {
+ for (int i = 0; i < COUNT; i++) {
+ resI[i] = (ints[i] * ints[i]);
+ }
+ }
+
+ @Benchmark
+ public void mulL() {
+ for (int i = 0; i < COUNT; i++) {
+ resL[i] = (longs[i] * longs[i]);
+ }
+ }
+
+ @Benchmark
+ public void absL() {
+ for (int i = 0; i < COUNT; i++) {
+ long a = longs[i];
+ resL[i] = (long) (Math.abs((long) a));
+ }
+ }
+
+ @Benchmark
+ public void rShiftL() {
+ for (int i = 0; i < COUNT; i++) {
+ resL[i] = longs[i] >> 3;
+ }
+ }
+
+ @Benchmark
+ public void absF() {
+ for (int i = 0; i < COUNT; i++) {
+ float a = floats[i];
+ resF[i] = (float) (Math.abs(a));
+ }
+ }
+
+ @Benchmark
+ public void negF() {
+ for (int i = 0; i < COUNT; i++) {
+ resF[i] = -floats[i];
+ }
+ }
+
+ @Benchmark
+ public void absD() {
+ for (int i = 0; i < COUNT; i++) {
+ double a = doubles[i];
+ resD[i] = (double) (Math.abs(a));
+ }
+ }
+
+ @Benchmark
+ public void negD() {
+ for (int i = 0; i < COUNT; i++) {
+ resD[i] = -doubles[i];
+ }
+ }
+
+ @Fork(value = 1, jvmArgsPrepend = {
+ "-XX:+UseSuperWord"
+ })
+ public static class TypeVectorOperationsSuperWord extends TypeVectorOperations {
+
+ }
+
+ @Fork(value = 1, jvmArgsPrepend = {
+ "-XX:-UseSuperWord"
+ })
+ public static class TypeVectorOperationsNonSuperWord extends TypeVectorOperations {
+ }
+
+}
--- a/test/nashorn/script/nosecurity/logcoverage.js Tue Jul 16 17:00:00 2019 -0700
+++ b/test/nashorn/script/nosecurity/logcoverage.js Mon Jul 22 11:08:27 2019 +0530
@@ -27,7 +27,7 @@
*
* @test
* @fork
- * @option -Dnashorn.debug=true
+ * @option -Dnashorn.debug=true -ot=true
*/
/*
@@ -98,8 +98,8 @@
print("check ok!");
}
-str = runScriptEngine(["--log=codegen,compiler=finest,methodhandles=finest,fields=finest"], __DIR__ + "../basic/NASHORN-19.js");
-str += runScriptEngine(["--log=codegen,compiler=finest,methodhandles=finest,fields=finest"], __DIR__ + "../basic/varargs.js");
+str = runScriptEngine(["--log=codegen,compiler=finest,methodhandles=finest,fields=finest", "-ot=true"], __DIR__ + "../basic/NASHORN-19.js");
+str += runScriptEngine(["--log=codegen,compiler=finest,methodhandles=finest,fields=finest", "-ot=true"], __DIR__ + "../basic/varargs.js");
check(str, methodsCalled);
check(str, ['return', 'get', 'set', '[fields]']);
--- a/test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test/BignumDtoaTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test/BignumDtoaTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -69,7 +69,7 @@
import static org.testng.Assert.assertTrue;
/**
- * FastDtoa tests
+ * BignumDtoa tests
*/
@SuppressWarnings("javadoc")
public class BignumDtoaTest {
@@ -220,6 +220,11 @@
assertEquals(299, buffer.getDecimalPoint());
buffer.reset();
+ DoubleConversion.bignumDtoa(1e-23, DtoaMode.SHORTEST, 0, buffer);
+ assertEquals("1", buffer.getRawDigits());
+ assertEquals(-22, buffer.getDecimalPoint());
+ buffer.reset();
+
final long smallest_normal64 = 0x0010000000000000L;
double v = Double.longBitsToDouble(smallest_normal64);
DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer);
--- a/test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test/FixedDtoaTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test/FixedDtoaTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -624,6 +624,11 @@
assertEquals("1000000000000000128", buffer.getRawDigits());
assertEquals(19, buffer.getDecimalPoint());
buffer.reset();
+
+ assertTrue(DoubleConversion.fixedDtoa(2.10861548515811875e+15, 17, buffer));
+ assertEquals("210861548515811875", buffer.getRawDigits());
+ assertEquals(16, buffer.getDecimalPoint());
+ buffer.reset();
}
--- a/test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test/IeeeDoubleTest.java Tue Jul 16 17:00:00 2019 -0700
+++ b/test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test/IeeeDoubleTest.java Mon Jul 22 11:08:27 2019 +0530
@@ -41,7 +41,11 @@
import static org.testng.Assert.assertTrue;
/**
- * Ieee class tests
+ * IeeeDouble tests
+ *
+ * @test
+ * @modules jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv:open
+ * @run testng jdk.nashorn.internal.runtime.doubleconv.test.IeeeDoubleTest
*/
@SuppressWarnings({"unchecked", "javadoc"})
public class IeeeDoubleTest {