--- a/.hgtags Wed Oct 16 01:16:12 2019 +0200
+++ b/.hgtags Wed Oct 16 11:23:46 2019 +0200
@@ -590,3 +590,4 @@
778fc2dcbdaa8981e07e929a2cacef979c72261e jdk-14+15
d29f0181ba424a95d881aba5eabf2e393abcc70f jdk-14+16
5c83830390baafb76a1fbe33443c57620bd45fb9 jdk-14+17
+e84d8379815ba0d3e50fb096d28c25894cb50b8c jdk-14+18
--- a/doc/building.html Wed Oct 16 01:16:12 2019 +0200
+++ b/doc/building.html Wed Oct 16 11:23:46 2019 +0200
@@ -281,7 +281,7 @@
<tbody>
<tr class="odd">
<td style="text-align: left;">Linux</td>
-<td style="text-align: left;">gcc 8.2.0</td>
+<td style="text-align: left;">gcc 8.3.0</td>
</tr>
<tr class="even">
<td style="text-align: left;">macOS</td>
@@ -293,14 +293,14 @@
</tr>
<tr class="even">
<td style="text-align: left;">Windows</td>
-<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.6</td>
+<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.16</td>
</tr>
</tbody>
</table>
<p>All compilers are expected to be able to compile to the C99 language standard, as some C99 features are used in the source code. Microsoft Visual Studio doesn't fully support C99 so in practice shared code is limited to using C99 features that it does support.</p>
<h3 id="gcc">gcc</h3>
<p>The minimum accepted version of gcc is 4.8. Older versions will generate a warning by <code>configure</code> and are unlikely to work.</p>
-<p>The JDK is currently known to be able to compile with at least version 7.4 of gcc.</p>
+<p>The JDK is currently known to be able to compile with at least version 8.3 of gcc.</p>
<p>In general, any version between these two should be usable.</p>
<h3 id="clang">clang</h3>
<p>The minimum accepted version of clang is 3.2. Older versions will not be accepted by <code>configure</code>.</p>
--- a/doc/building.md Wed Oct 16 01:16:12 2019 +0200
+++ b/doc/building.md Wed Oct 16 11:23:46 2019 +0200
@@ -323,10 +323,10 @@
Operating system Toolchain version
------------------ -------------------------------------------------------
- Linux gcc 8.2.0
+ Linux gcc 8.3.0
macOS Apple Xcode 10.1 (using clang 10.0.0)
Solaris Oracle Solaris Studio 12.6 (with compiler version 5.15)
- Windows Microsoft Visual Studio 2017 update 15.9.6
+ Windows Microsoft Visual Studio 2017 update 15.9.16
All compilers are expected to be able to compile to the C99 language standard,
as some C99 features are used in the source code. Microsoft Visual Studio
@@ -338,7 +338,7 @@
The minimum accepted version of gcc is 4.8. Older versions will generate a warning
by `configure` and are unlikely to work.
-The JDK is currently known to be able to compile with at least version 7.4 of
+The JDK is currently known to be able to compile with at least version 8.3 of
gcc.
In general, any version between these two should be usable.
--- a/make/RunTestsPrebuilt.gmk Wed Oct 16 01:16:12 2019 +0200
+++ b/make/RunTestsPrebuilt.gmk Wed Oct 16 11:23:46 2019 +0200
@@ -230,7 +230,7 @@
NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu)
MEMORY_SIZE := $(shell $(EXPR) `/usr/sbin/sysctl -n hw.memsize` / 1024 / 1024)
else ifeq ($(OPENJDK_TARGET_OS), solaris)
- NUM_CORES := $(shell LC_MESSAGES=C /usr/sbin/psrinfo -v | $(GREP) -c on-line)
+ NUM_CORES := $(shell /usr/sbin/psrinfo -v | $(GREP) -c on-line)
MEMORY_SIZE := $(shell \
/usr/sbin/prtconf 2> /dev/null | $(GREP) "^Memory [Ss]ize" | $(AWK) '{print $$3}' \
)
--- a/make/RunTestsPrebuiltSpec.gmk Wed Oct 16 01:16:12 2019 +0200
+++ b/make/RunTestsPrebuiltSpec.gmk Wed Oct 16 11:23:46 2019 +0200
@@ -27,6 +27,9 @@
# Fake minimalistic spec file for RunTestsPrebuilt.gmk.
################################################################################
+# Make sure all shell commands are executed with the C locale
+export LC_ALL := C
+
define VerifyVariable
ifeq ($$($1), )
$$(info Error: Variable $1 is missing, needed by RunTestPrebuiltSpec.gmk)
--- a/make/autoconf/basics.m4 Wed Oct 16 01:16:12 2019 +0200
+++ b/make/autoconf/basics.m4 Wed Oct 16 11:23:46 2019 +0200
@@ -427,7 +427,7 @@
# Save the path variable before it gets changed
ORIGINAL_PATH="$PATH"
AC_SUBST(ORIGINAL_PATH)
- DATE_WHEN_CONFIGURED=`LANG=C date`
+ DATE_WHEN_CONFIGURED=`date`
AC_SUBST(DATE_WHEN_CONFIGURED)
AC_MSG_NOTICE([Configuration created at $DATE_WHEN_CONFIGURED.])
])
--- a/make/autoconf/build-performance.m4 Wed Oct 16 01:16:12 2019 +0200
+++ b/make/autoconf/build-performance.m4 Wed Oct 16 11:23:46 2019 +0200
@@ -35,7 +35,7 @@
FOUND_CORES=yes
elif test -x /usr/sbin/psrinfo; then
# Looks like a Solaris system
- NUM_CORES=`LC_MESSAGES=C /usr/sbin/psrinfo -v | grep -c on-line`
+ NUM_CORES=`/usr/sbin/psrinfo -v | grep -c on-line`
FOUND_CORES=yes
elif test -x /usr/sbin/sysctl; then
# Looks like a MacOSX system
--- a/make/autoconf/configure Wed Oct 16 01:16:12 2019 +0200
+++ b/make/autoconf/configure Wed Oct 16 11:23:46 2019 +0200
@@ -43,6 +43,9 @@
export CONFIG_SHELL=$BASH
export _as_can_reexec=no
+# Make sure all shell commands are executed with the C locale
+export LC_ALL=C
+
if test "x$CUSTOM_CONFIG_DIR" != x; then
custom_hook=$CUSTOM_CONFIG_DIR/custom-hook.m4
if test ! -e $custom_hook; then
--- a/make/autoconf/spec.gmk.in Wed Oct 16 01:16:12 2019 +0200
+++ b/make/autoconf/spec.gmk.in Wed Oct 16 11:23:46 2019 +0200
@@ -51,6 +51,9 @@
# What make to use for main processing, after bootstrapping top-level Makefile.
MAKE := @MAKE@
+# Make sure all shell commands are executed with the C locale
+export LC_ALL := C
+
# The default make arguments
MAKE_ARGS = $(MAKE_LOG_FLAGS) -r -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" $(MAKE_LOG_VARS)
--- a/make/autoconf/toolchain_windows.m4 Wed Oct 16 01:16:12 2019 +0200
+++ b/make/autoconf/toolchain_windows.m4 Wed Oct 16 11:23:46 2019 +0200
@@ -209,6 +209,8 @@
eval SDK_INSTALL_DIR="\${VS_SDK_INSTALLDIR_${VS_VERSION}}"
eval VS_ENV_ARGS="\${VS_ENV_ARGS_${VS_VERSION}}"
eval VS_TOOLSET_SUPPORTED="\${VS_TOOLSET_SUPPORTED_${VS_VERSION}}"
+
+ VS_ENV_CMD=""
# When using --with-tools-dir, assume it points to the correct and default
# version of Visual Studio or that --with-toolchain-version was also set.
@@ -227,8 +229,6 @@
fi
fi
- VS_ENV_CMD=""
-
if test "x$VS_COMNTOOLS" != x; then
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}],
[$VS_COMNTOOLS/../..], [$VS_COMNTOOLS_VAR variable])
--- a/make/common/JavaCompilation.gmk Wed Oct 16 01:16:12 2019 +0200
+++ b/make/common/JavaCompilation.gmk Wed Oct 16 11:23:46 2019 +0200
@@ -122,7 +122,7 @@
$$($1_BIN)$$($1_MODULE_SUBDIR)$$($2_TARGET) : $2
$$(call LogInfo, Cleaning $$(patsubst $(OUTPUTDIR)/%,%, $$@))
$$(call MakeTargetDir)
- export LC_ALL=C ; ( $(CAT) $$< && $(ECHO) "" ) \
+ ( $(CAT) $$< && $(ECHO) "" ) \
| $(SED) -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' \
-e 's/\([^\\]\)!/\1\\!/g' -e 's/^[ ]*#.*/#/g' \
| $(SED) -f "$(TOPDIR)/make/common/support/unicode2x.sed" \
--- a/make/conf/jib-profiles.js Wed Oct 16 01:16:12 2019 +0200
+++ b/make/conf/jib-profiles.js Wed Oct 16 11:23:46 2019 +0200
@@ -944,11 +944,11 @@
var getJibProfilesDependencies = function (input, common) {
var devkit_platform_revisions = {
- linux_x64: "gcc8.2.0-OL6.4+1.0",
+ linux_x64: "gcc8.3.0-OL6.4+1.0",
macosx_x64: "Xcode10.1-MacOSX10.14+1.0",
solaris_x64: "SS12u4-Solaris11u1+1.0",
solaris_sparcv9: "SS12u6-Solaris11u3+1.0",
- windows_x64: "VS2017-15.9.6+1.0",
+ windows_x64: "VS2017-15.9.16+1.0",
linux_aarch64: "gcc8.2.0-Fedora27+1.0",
linux_arm: "gcc8.2.0-Fedora27+1.0",
linux_ppc64le: "gcc8.2.0-Fedora27+1.0",
--- a/make/data/charsetmapping/SingleByte-X.java.template Wed Oct 16 01:16:12 2019 +0200
+++ b/make/data/charsetmapping/SingleByte-X.java.template Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -48,7 +48,7 @@
}
public CharsetDecoder newDecoder() {
- return new SingleByte.Decoder(this, b2c, $ASCIICOMPATIBLE$);
+ return new SingleByte.Decoder(this, b2c, $ASCIICOMPATIBLE$, $LATIN1DECODABLE$);
}
public CharsetEncoder newEncoder() {
--- a/make/data/lsrdata/language-subtag-registry.txt Wed Oct 16 01:16:12 2019 +0200
+++ b/make/data/lsrdata/language-subtag-registry.txt Wed Oct 16 11:23:46 2019 +0200
@@ -1,4 +1,4 @@
-File-Date: 2019-04-03
+File-Date: 2019-09-16
%%
Type: language
Subtag: aa
@@ -2096,6 +2096,8 @@
Subtag: ais
Description: Nataoran Amis
Added: 2009-07-29
+Deprecated: 2019-04-16
+Comments: see ami, szy
%%
Type: language
Subtag: ait
@@ -2633,6 +2635,7 @@
Type: language
Subtag: ant
Description: Antakarinya
+Description: Antikarinya
Added: 2009-07-29
%%
Type: language
@@ -3094,6 +3097,8 @@
Subtag: asd
Description: Asas
Added: 2009-07-29
+Deprecated: 2019-04-16
+Preferred-Value: snz
%%
Type: language
Subtag: ase
@@ -4135,7 +4140,7 @@
%%
Type: language
Subtag: bck
-Description: Bunaba
+Description: Bunuba
Added: 2009-07-29
%%
Type: language
@@ -6930,7 +6935,7 @@
%%
Type: language
Subtag: bym
-Description: Bidyara
+Description: Bidjara
Added: 2009-07-29
%%
Type: language
@@ -7564,6 +7569,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: cey
+Description: Ekai Chin
+Added: 2019-04-16
+%%
+Type: language
Subtag: cfa
Description: Dijim-Bwilim
Added: 2009-07-29
@@ -9439,6 +9449,7 @@
Type: language
Subtag: dif
Description: Dieri
+Description: Diyari
Added: 2009-07-29
%%
Type: language
@@ -9515,6 +9526,8 @@
Subtag: dit
Description: Dirari
Added: 2009-07-29
+Deprecated: 2019-04-29
+Preferred-Value: dif
%%
Type: language
Subtag: diu
@@ -9560,6 +9573,7 @@
Type: language
Subtag: djd
Description: Djamindjung
+Description: Ngaliwurru
Added: 2009-07-29
%%
Type: language
@@ -9603,6 +9617,7 @@
%%
Type: language
Subtag: djn
+Description: Jawoyn
Description: Djauan
Added: 2009-07-29
%%
@@ -10191,6 +10206,8 @@
Subtag: dud
Description: Hun-Saare
Added: 2009-07-29
+Deprecated: 2019-04-16
+Comments: see uth, uss
%%
Type: language
Subtag: due
@@ -10382,6 +10399,7 @@
Type: language
Subtag: dyn
Description: Dyangadi
+Description: Dhanggatti
Added: 2009-07-29
%%
Type: language
@@ -10396,6 +10414,7 @@
%%
Type: language
Subtag: dyy
+Description: Djabugay
Description: Dyaabugay
Added: 2009-07-29
%%
@@ -11672,7 +11691,7 @@
%%
Type: language
Subtag: gbd
-Description: Karadjeri
+Description: Karajarri
Added: 2009-07-29
%%
Type: language
@@ -12056,7 +12075,7 @@
%%
Type: language
Subtag: gge
-Description: Guragone
+Description: Gurr-goni
Added: 2009-07-29
%%
Type: language
@@ -12169,7 +12188,7 @@
%%
Type: language
Subtag: gia
-Description: Kitja
+Description: Kija
Added: 2009-07-29
%%
Type: language
@@ -12955,7 +12974,7 @@
%%
Type: language
Subtag: gue
-Description: Gurinji
+Description: Gurindji
Added: 2009-07-29
%%
Type: language
@@ -15292,6 +15311,7 @@
Type: language
Subtag: jay
Description: Yan-nhangu
+Description: Nhangu
Added: 2009-07-29
%%
Type: language
@@ -15488,6 +15508,7 @@
%%
Type: language
Subtag: jig
+Description: Jingulu
Description: Djingili
Added: 2009-07-29
%%
@@ -17222,6 +17243,7 @@
Type: language
Subtag: kkp
Description: Gugubera
+Description: Koko-Bera
Added: 2009-07-29
%%
Type: language
@@ -17266,6 +17288,7 @@
%%
Type: language
Subtag: kky
+Description: Guugu Yimidhirr
Description: Guguyimidjir
Added: 2009-07-29
%%
@@ -18320,6 +18343,7 @@
Type: language
Subtag: ktd
Description: Kokata
+Description: Kukatha
Added: 2009-07-29
%%
Type: language
@@ -19341,6 +19365,7 @@
Subtag: lba
Description: Lui
Added: 2009-07-29
+Deprecated: 2019-04-16
%%
Type: language
Subtag: lbb
@@ -19396,7 +19421,7 @@
%%
Type: language
Subtag: lbn
-Description: Lamet
+Description: Rmeet
Added: 2009-07-29
%%
Type: language
@@ -19446,6 +19471,7 @@
%%
Type: language
Subtag: lby
+Description: Lamalama
Description: Lamu-Lamu
Added: 2009-07-29
%%
@@ -20162,6 +20188,8 @@
Subtag: llo
Description: Khlor
Added: 2009-07-29
+Deprecated: 2019-04-16
+Preferred-Value: ngt
%%
Type: language
Subtag: llp
@@ -20654,6 +20682,11 @@
Macrolanguage: luy
%%
Type: language
+Subtag: lsn
+Description: Tibetan Sign Language
+Added: 2019-04-16
+%%
+Type: language
Subtag: lso
Description: Laos Sign Language
Added: 2009-07-29
@@ -20680,6 +20713,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: lsv
+Description: Sivia Sign Language
+Added: 2019-04-16
+%%
+Type: language
Subtag: lsy
Description: Mauritian Sign Language
Added: 2010-03-11
@@ -20848,6 +20886,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: lvi
+Description: Lavi
+Added: 2019-04-16
+%%
+Type: language
Subtag: lvk
Description: Lavukaleve
Added: 2009-07-29
@@ -21454,7 +21497,7 @@
%%
Type: language
Subtag: mec
-Description: Mara
+Description: Marra
Added: 2009-07-29
%%
Type: language
@@ -21523,7 +21566,7 @@
%%
Type: language
Subtag: mep
-Description: Miriwung
+Description: Miriwoong
Added: 2009-07-29
%%
Type: language
@@ -21660,7 +21703,7 @@
%%
Type: language
Subtag: mfr
-Description: Marithiel
+Description: Marrithiyel
Added: 2009-07-29
%%
Type: language
@@ -22853,12 +22896,13 @@
%%
Type: language
Subtag: mpb
+Description: Malak Malak
Description: Mullukmulluk
Added: 2009-07-29
%%
Type: language
Subtag: mpc
-Description: Mangarayi
+Description: Mangarrayi
Added: 2009-07-29
%%
Type: language
@@ -22889,6 +22933,7 @@
Type: language
Subtag: mpj
Description: Martu Wangka
+Description: Wangkajunga
Added: 2009-07-29
%%
Type: language
@@ -24015,6 +24060,8 @@
Subtag: myd
Description: Maramba
Added: 2009-07-29
+Deprecated: 2019-04-16
+Preferred-Value: aog
%%
Type: language
Subtag: mye
@@ -24040,6 +24087,7 @@
Subtag: myi
Description: Mina (India)
Added: 2009-07-29
+Deprecated: 2019-04-16
%%
Type: language
Subtag: myj
@@ -24375,7 +24423,7 @@
%%
Type: language
Subtag: nay
-Description: Narrinyeri
+Description: Ngarrindjeri
Added: 2009-07-29
%%
Type: language
@@ -24432,7 +24480,7 @@
%%
Type: language
Subtag: nbj
-Description: Ngarinman
+Description: Ngarinyman
Added: 2009-07-29
%%
Type: language
@@ -24467,7 +24515,7 @@
%%
Type: language
Subtag: nbr
-Description: Numana-Nunku-Gbantu-Numbu
+Description: Numana
Added: 2009-07-29
%%
Type: language
@@ -24559,7 +24607,7 @@
%%
Type: language
Subtag: nck
-Description: Nakara
+Description: Na-kara
Added: 2009-07-29
%%
Type: language
@@ -24931,7 +24979,7 @@
%%
Type: language
Subtag: ngh
-Description: Nǀu
+Description: Nǁng
Added: 2009-07-29
%%
Type: language
@@ -25176,7 +25224,7 @@
%%
Type: language
Subtag: nig
-Description: Ngalakan
+Description: Ngalakgan
Added: 2009-07-29
%%
Type: language
@@ -25798,6 +25846,8 @@
Subtag: nns
Description: Ningye
Added: 2009-07-29
+Deprecated: 2019-04-16
+Preferred-Value: nbr
%%
Type: language
Subtag: nnt
@@ -26658,7 +26708,7 @@
%%
Type: language
Subtag: nyh
-Description: Nyigina
+Description: Nyikina
Added: 2009-07-29
%%
Type: language
@@ -26713,7 +26763,7 @@
%%
Type: language
Subtag: nys
-Description: Nyunga
+Description: Nyungar
Added: 2009-07-29
%%
Type: language
@@ -28707,6 +28757,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: pnd
+Description: Mpinda
+Added: 2019-04-16
+%%
+Type: language
Subtag: pne
Description: Western Penan
Added: 2009-07-29
@@ -28794,6 +28849,7 @@
%%
Type: language
Subtag: pnw
+Description: Banyjima
Description: Panytyima
Added: 2009-07-29
%%
@@ -29251,7 +29307,8 @@
%%
Type: language
Subtag: pti
-Description: Pintiini
+Description: Pindiini
+Description: Wangkatha
Added: 2009-07-29
%%
Type: language
@@ -30133,6 +30190,7 @@
%%
Type: language
Subtag: ril
+Description: Riang Lang
Description: Riang (Myanmar)
Added: 2009-07-29
%%
@@ -30153,7 +30211,7 @@
%%
Type: language
Subtag: rit
-Description: Ritarungo
+Description: Ritharrngu
Added: 2009-07-29
%%
Type: language
@@ -30219,7 +30277,7 @@
%%
Type: language
Subtag: rmb
-Description: Rembarunga
+Description: Rembarrnga
Added: 2009-07-29
%%
Type: language
@@ -30641,6 +30699,7 @@
Type: language
Subtag: rxw
Description: Karuwali
+Description: Garuwali
Added: 2013-09-10
%%
Type: language
@@ -32206,7 +32265,7 @@
%%
Type: language
Subtag: snz
-Description: Sinsauru
+Description: Kou
Added: 2009-07-29
%%
Type: language
@@ -32883,6 +32942,7 @@
Subtag: suj
Description: Shubi
Added: 2009-07-29
+Comments: see also xsj
%%
Type: language
Subtag: suk
@@ -33312,6 +33372,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: szy
+Description: Sakizaya
+Added: 2019-04-16
+%%
+Type: language
Subtag: taa
Description: Lower Tanana
Added: 2009-07-29
@@ -33465,6 +33530,7 @@
%%
Type: language
Subtag: tbh
+Description: Dharawal
Description: Thurawal
Added: 2009-07-29
%%
@@ -33644,6 +33710,7 @@
Type: language
Subtag: tcs
Description: Torres Strait Creole
+Description: Yumplatok
Added: 2009-07-29
%%
Type: language
@@ -34067,6 +34134,7 @@
%%
Type: language
Subtag: thd
+Description: Kuuk Thaayorre
Description: Thayore
Added: 2009-07-29
%%
@@ -34310,6 +34378,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: tjj
+Description: Tjungundji
+Added: 2019-04-16
+%%
+Type: language
Subtag: tjl
Description: Tai Laing
Added: 2012-08-12
@@ -34330,6 +34403,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: tjp
+Description: Tjupany
+Added: 2019-04-16
+%%
+Type: language
Subtag: tjs
Description: Southern Tujia
Added: 2009-07-29
@@ -35679,6 +35757,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: tvx
+Description: Taivoan
+Added: 2019-04-16
+%%
+Type: language
Subtag: tvy
Description: Timor Pidgin
Added: 2009-07-29
@@ -36230,7 +36313,7 @@
%%
Type: language
Subtag: ulk
-Description: Meriam
+Description: Meriam Mir
Added: 2009-07-29
%%
Type: language
@@ -36280,6 +36363,7 @@
%%
Type: language
Subtag: umg
+Description: Morrobalama
Description: Umbuygamu
Added: 2009-07-29
%%
@@ -36550,6 +36634,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: uss
+Description: us-Saare
+Added: 2019-04-16
+%%
+Type: language
Subtag: usu
Description: Uya
Added: 2009-07-29
@@ -36565,6 +36654,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: uth
+Description: ut-Hun
+Added: 2019-04-16
+%%
+Type: language
Subtag: utp
Description: Amba (Solomon Islands)
Added: 2009-07-29
@@ -37178,7 +37272,7 @@
%%
Type: language
Subtag: waq
-Description: Wageman
+Description: Wagiman
Added: 2009-07-29
%%
Type: language
@@ -37301,7 +37395,7 @@
%%
Type: language
Subtag: wbt
-Description: Wanman
+Description: Warnman
Added: 2009-07-29
%%
Type: language
@@ -37448,6 +37542,7 @@
%%
Type: language
Subtag: wgg
+Description: Wangkangurru
Description: Wangganguru
Added: 2009-07-29
%%
@@ -37521,7 +37616,7 @@
%%
Type: language
Subtag: wig
-Description: Wik-Ngathana
+Description: Wik Ngathan
Added: 2009-07-29
%%
Type: language
@@ -37625,6 +37720,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: wkr
+Description: Keerray-Woorroong
+Added: 2019-04-16
+%%
+Type: language
Subtag: wku
Description: Kunduvadi
Added: 2009-07-29
@@ -37857,10 +37957,12 @@
Type: language
Subtag: wny
Description: Wanyi
+Description: Waanyi
Added: 2012-08-12
%%
Type: language
Subtag: woa
+Description: Kuwema
Description: Tyaraity
Added: 2009-07-29
%%
@@ -37951,6 +38053,7 @@
%%
Type: language
Subtag: wrb
+Description: Waluwarra
Description: Warluwara
Added: 2009-07-29
%%
@@ -37962,11 +38065,12 @@
Type: language
Subtag: wrg
Description: Warungu
+Description: Gudjal
Added: 2009-07-29
%%
Type: language
Subtag: wrh
-Description: Wiradhuri
+Description: Wiradjuri
Added: 2009-07-29
%%
Type: language
@@ -38439,6 +38543,7 @@
%%
Type: language
Subtag: xby
+Description: Batjala
Description: Batyala
Added: 2013-09-10
%%
@@ -38998,7 +39103,7 @@
%%
Type: language
Subtag: xmh
-Description: Kuku-Muminh
+Description: Kugu-Muminh
Added: 2009-07-29
%%
Type: language
@@ -39423,8 +39528,7 @@
Subtag: xsj
Description: Subi
Added: 2009-07-29
-Deprecated: 2015-02-12
-Preferred-Value: suj
+Comments: see also suj
%%
Type: language
Subtag: xsl
@@ -40258,6 +40362,7 @@
%%
Type: language
Subtag: yin
+Description: Riang Lai
Description: Yinchia
Added: 2009-07-29
%%
@@ -41562,12 +41667,13 @@
%%
Type: language
Subtag: zml
-Description: Madngele
+Description: Matngala
Added: 2009-07-29
%%
Type: language
Subtag: zmm
Description: Marimanindji
+Description: Marramaninyshi
Added: 2009-07-29
%%
Type: language
@@ -43019,6 +43125,13 @@
Prefix: sgn
%%
Type: extlang
+Subtag: lsn
+Description: Tibetan Sign Language
+Added: 2019-04-16
+Preferred-Value: lsn
+Prefix: sgn
+%%
+Type: extlang
Subtag: lso
Description: Laos Sign Language
Added: 2009-07-29
@@ -43041,6 +43154,13 @@
Prefix: sgn
%%
Type: extlang
+Subtag: lsv
+Description: Sivia Sign Language
+Added: 2019-04-16
+Preferred-Value: lsv
+Prefix: sgn
+%%
+Type: extlang
Subtag: lsy
Description: Mauritian Sign Language
Added: 2010-03-11
@@ -43966,6 +44086,11 @@
Added: 2005-10-16
%%
Type: script
+Subtag: Chrs
+Description: Chorasmian
+Added: 2019-09-11
+%%
+Type: script
Subtag: Cirt
Description: Cirth
Added: 2005-10-16
@@ -44002,6 +44127,11 @@
Added: 2005-10-16
%%
Type: script
+Subtag: Diak
+Description: Dives Akuru
+Added: 2019-09-11
+%%
+Type: script
Subtag: Dogr
Description: Dogra
Added: 2017-01-13
@@ -44839,6 +44969,11 @@
Added: 2005-10-16
%%
Type: script
+Subtag: Yezi
+Description: Yezidi
+Added: 2019-09-11
+%%
+Type: script
Subtag: Yiii
Description: Yi
Added: 2005-10-16
@@ -45683,7 +45818,7 @@
%%
Type: region
Subtag: MK
-Description: The Former Yugoslav Republic of Macedonia
+Description: North Macedonia
Added: 2005-10-16
%%
Type: region
--- a/make/devkit/Tools.gmk Wed Oct 16 01:16:12 2019 +0200
+++ b/make/devkit/Tools.gmk Wed Oct 16 11:23:46 2019 +0200
@@ -79,20 +79,19 @@
# Define external dependencies
# Latest that could be made to work.
-GCC_VER := 8.2.0
-ifeq ($(GCC_VER), 8.2.0)
- gcc_ver := gcc-8.2.0
- binutils_ver := binutils-2.30
- ccache_ver := ccache-3.5.1a
- CCACHE_DIRNAME := ccache-3.5.1
+GCC_VER := 8.3.0
+ifeq ($(GCC_VER), 8.3.0)
+ gcc_ver := gcc-8.3.0
+ binutils_ver := binutils-2.32
+ ccache_ver := 3.7.3
mpfr_ver := mpfr-3.1.5
gmp_ver := gmp-6.1.2
mpc_ver := mpc-1.0.3
- gdb_ver := gdb-8.2.1
+ gdb_ver := gdb-8.3
else ifeq ($(GCC_VER), 7.3.0)
gcc_ver := gcc-7.3.0
binutils_ver := binutils-2.30
- ccache_ver := ccache-3.3.6
+ ccache_ver := 3.3.6
mpfr_ver := mpfr-3.1.5
gmp_ver := gmp-6.1.2
mpc_ver := mpc-1.0.3
@@ -100,7 +99,7 @@
else ifeq ($(GCC_VER), 4.9.2)
gcc_ver := gcc-4.9.2
binutils_ver := binutils-2.25
- ccache_ver := ccache-3.2.1
+ ccache_ver := 3.2.1
mpfr_ver := mpfr-3.0.1
gmp_ver := gmp-4.3.2
mpc_ver := mpc-1.0.1
@@ -111,7 +110,7 @@
GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.xz
BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.xz
-CCACHE := https://samba.org/ftp/ccache/$(ccache_ver).tar.xz
+CCACHE := https://github.com/ccache/ccache/releases/download/v$(ccache_ver)/ccache-$(ccache_ver).tar.xz
MPFR := https://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
GMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2
MPC := http://ftp.gnu.org/pub/gnu/mpc/${mpc_ver}.tar.gz
--- a/make/devkit/createWindowsDevkit2017.sh Wed Oct 16 01:16:12 2019 +0200
+++ b/make/devkit/createWindowsDevkit2017.sh Wed Oct 16 11:23:46 2019 +0200
@@ -32,10 +32,7 @@
VS_VERSION_NUM_NODOT="150"
VS_DLL_VERSION="140"
SDK_VERSION="10"
-SDK_FULL_VERSION="10.0.16299.0"
MSVC_DIR="Microsoft.VC141.CRT"
-MSVC_FULL_VERSION="14.12.25827"
-REDIST_FULL_VERSION="14.12.25810"
SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
BUILD_DIR="${SCRIPT_DIR}/../../build/devkit"
--- a/make/jdk/src/classes/build/tools/charsetmapping/SBCS.java Wed Oct 16 01:16:12 2019 +0200
+++ b/make/jdk/src/classes/build/tools/charsetmapping/SBCS.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, 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
@@ -46,6 +46,7 @@
String hisName = cs.hisName;
String pkgName = cs.pkgName;
boolean isASCII = cs.isASCII;
+ boolean isLatin1Decodable = true;
StringBuilder b2cSB = new StringBuilder();
StringBuilder b2cNRSB = new StringBuilder();
@@ -69,6 +70,9 @@
c2bOff += 0x100;
c2bIndex[e.cp>>8] = 1;
}
+ if (e.cp > 0xFF) {
+ isLatin1Decodable = false;
+ }
}
Formatter fm = new Formatter(b2cSB);
@@ -178,6 +182,9 @@
if (line.indexOf("$ASCIICOMPATIBLE$") != -1) {
line = line.replace("$ASCIICOMPATIBLE$", isASCII ? "true" : "false");
}
+ if (line.indexOf("$LATIN1DECODABLE$") != -1) {
+ line = line.replace("$LATIN1DECODABLE$", isLatin1Decodable ? "true" : "false");
+ }
if (line.indexOf("$B2CTABLE$") != -1) {
line = line.replace("$B2CTABLE$", b2c);
}
--- a/make/scripts/compare.sh Wed Oct 16 01:16:12 2019 +0200
+++ b/make/scripts/compare.sh Wed Oct 16 11:23:46 2019 +0200
@@ -34,6 +34,9 @@
exit 1
fi
+# Make sure all shell commands are executed with the C locale
+export LC_ALL=C
+
if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
FULLDUMP_CMD="$OTOOL -v -V -h -X -d"
LDD_CMD="$OTOOL -L"
@@ -110,7 +113,7 @@
"
fi
elif [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
- DIS_DIFF_FILTER="LANG=C $SED \
+ DIS_DIFF_FILTER="$SED \
-e 's/0x[0-9a-f]\{3,16\}/<HEXSTR>/g' -e 's/^[0-9a-f]\{12,20\}/<ADDR>/' \
-e 's/-20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]-[0-2][0-9]\{5\}/<DATE>/g' \
-e 's/), built on .*/), <DATE>/' \
@@ -134,7 +137,7 @@
if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then
# Filter out date string, ant version and java version differences.
- TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
+ TMP=$($DIFF $OTHER_FILE $THIS_FILE | \
$GREP '^[<>]' | \
$SED -e '/[<>] Ant-Version: Apache Ant .*/d' \
-e '/[<>] Created-By: .* (Oracle [Corpatin)]*/d' \
@@ -142,7 +145,7 @@
-e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d')
fi
if test "x$SUFFIX" = "xjava"; then
- TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
+ TMP=$($DIFF $OTHER_FILE $THIS_FILE | \
$GREP '^[<>]' | \
$SED -e '/[<>] \* from.*\.idl/d' \
-e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
@@ -197,7 +200,7 @@
fi
if test "x$SUFFIX" = "xproperties"; then
# Filter out date string differences.
- TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
+ TMP=$($DIFF $OTHER_FILE $THIS_FILE | \
$GREP '^[<>]' | \
$SED -e '/[<>].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d')
fi
@@ -207,7 +210,7 @@
-e 's/<font size=-1>/<font size=\"-1\">/g'"
$CAT $THIS_FILE | eval "$HTML_FILTER" > $THIS_FILE.filtered
$CAT $OTHER_FILE | eval "$HTML_FILTER" > $OTHER_FILE.filtered
- TMP=$(LC_ALL=C $DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \
+ TMP=$($DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \
$GREP '^[<>]' | \
$SED -e '/[<>] <!-- Generated by javadoc .* on .* -->/d' \
-e '/[<>] <meta name="date" content=".*">/d' )
@@ -554,11 +557,11 @@
CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff
# On solaris, there is no -q option.
if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
- LC_ALL=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \
+ $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \
| $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \
> $CONTENTS_DIFF_FILE
else
- LC_ALL=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE
+ $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE
fi
ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE)
@@ -605,11 +608,11 @@
if [ -n "$SHOW_DIFFS" ]; then
for i in $(cat $WORK_DIR/$ZIP_FILE.difflist) ; do
if [ -f "${OTHER_UNZIPDIR}/$i.javap" ]; then
- LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap
+ $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap
elif [ -f "${OTHER_UNZIPDIR}/$i.cleaned" ]; then
- LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i
+ $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i
else
- LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i
+ $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i
fi
done
fi
@@ -642,7 +645,7 @@
$JMOD list $THIS_JMOD | sort > $THIS_JMOD_LIST
$JMOD list $OTHER_JMOD | sort > $OTHER_JMOD_LIST
JMOD_LIST_DIFF_FILE=$WORK_DIR/$JMOD_FILE.list.diff
- LC_ALL=C $DIFF $THIS_JMOD_LIST $OTHER_JMOD_LIST > $JMOD_LIST_DIFF_FILE
+ $DIFF $THIS_JMOD_LIST $OTHER_JMOD_LIST > $JMOD_LIST_DIFF_FILE
ONLY_THIS=$($GREP "^<" $JMOD_LIST_DIFF_FILE)
ONLY_OTHER=$($GREP "^>" $JMOD_LIST_DIFF_FILE)
@@ -924,7 +927,7 @@
> $WORK_FILE_BASE.symbols.this
fi
- LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff
+ $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff
if [ -s $WORK_FILE_BASE.symbols.diff ]; then
SYM_MSG=" diff "
if [[ "$ACCEPTED_SYM_DIFF" != *"$BIN_FILE"* ]]; then
@@ -964,9 +967,9 @@
| $UNIQ > $WORK_FILE_BASE.deps.this.uniq)
(cd $FILE_WORK_DIR && $RM -f $NAME)
- LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this \
+ $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this \
> $WORK_FILE_BASE.deps.diff
- LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq \
+ $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq \
> $WORK_FILE_BASE.deps.diff.uniq
if [ -s $WORK_FILE_BASE.deps.diff ]; then
@@ -1016,7 +1019,7 @@
> $WORK_FILE_BASE.fulldump.this 2>&1 &
wait
- LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \
+ $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \
> $WORK_FILE_BASE.fulldump.diff
if [ -s $WORK_FILE_BASE.fulldump.diff ]; then
@@ -1063,7 +1066,7 @@
| eval "$this_DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 &
wait
- LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff
+ $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff
if [ -s $WORK_FILE_BASE.dis.diff ]; then
DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}')
--- a/src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -26,6 +26,7 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "utilities/align.hpp"
--- a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -185,6 +185,10 @@
NativeMovConstReg* method_holder
= nativeMovConstReg_at(stub + NativeInstruction::instruction_size);
method_holder->set_data(0);
+ if (!static_stub->is_aot()) {
+ NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
+ jump->set_jump_destination((address)-1);
+ }
}
//-----------------------------------------------------------------------------
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -332,9 +332,14 @@
// We use jump to self as the unresolved address which the inline
// cache code (and relocs) know about
+ // As a special case we also use sequence movptr(r,0); br(r);
+ // i.e. jump to 0 when we need leave space for a wide immediate
+ // load
- // return -1 if jump to self
- dest = (dest == (address) this) ? (address) -1 : dest;
+ // return -1 if jump to self or to 0
+ if ((dest == (address)this) || dest == 0) {
+ dest = (address) -1;
+ }
return dest;
}
@@ -356,9 +361,13 @@
// We use jump to self as the unresolved address which the inline
// cache code (and relocs) know about
+ // As a special case we also use jump to 0 when first generating
+ // a general jump
- // return -1 if jump to self
- dest = (dest == (address) this) ? (address) -1 : dest;
+ // return -1 if jump to self or to 0
+ if ((dest == (address)this) || dest == 0) {
+ dest = (address) -1;
+ }
return dest;
}
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -34,6 +34,7 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
--- a/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -27,6 +27,7 @@
#include "interpreter/bytecode.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
--- a/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -26,6 +26,7 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "utilities/debug.hpp"
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "nativeInst_ppc.hpp"
+#include "oops/klass.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -34,6 +34,7 @@
#include "interpreter/interp_masm.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "interpreter/templateInterpreter.hpp"
#include "interpreter/templateTable.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
--- a/src/hotspot/cpu/ppc/vtableStubs_ppc_64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/ppc/vtableStubs_ppc_64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -30,6 +30,7 @@
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_ppc.inline.hpp"
--- a/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -26,6 +26,7 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "utilities/debug.hpp"
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -33,6 +33,7 @@
#include "interpreter/interp_masm.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "registerSaver_s390.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
--- a/src/hotspot/cpu/s390/vtableStubs_s390.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/s390/vtableStubs_s390.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -30,6 +30,7 @@
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_s390.inline.hpp"
--- a/src/hotspot/cpu/sparc/abstractInterpreter_sparc.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/sparc/abstractInterpreter_sparc.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "runtime/arguments.hpp"
#include "runtime/frame.inline.hpp"
--- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
--- a/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciMethod.hpp"
#include "interpreter/interpreter.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/frame.inline.hpp"
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -824,11 +824,13 @@
}
void MacroAssembler::stop(const char* msg) {
- address rip = pc();
- pusha(); // get regs on stack
+ if (ShowMessageBoxOnError) {
+ address rip = pc();
+ pusha(); // get regs on stack
+ lea(c_rarg1, InternalAddress(rip));
+ movq(c_rarg2, rsp); // pass pointer to regs array
+ }
lea(c_rarg0, ExternalAddress((address) msg));
- lea(c_rarg1, InternalAddress(rip));
- movq(c_rarg2, rsp); // pass pointer to regs array
andq(rsp, -16); // align stack as required by ABI
call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)));
hlt();
@@ -6350,7 +6352,7 @@
movptr(result, str1);
if (UseAVX >= 2) {
cmpl(cnt1, stride);
- jcc(Assembler::less, SCAN_TO_CHAR_LOOP);
+ jcc(Assembler::less, SCAN_TO_CHAR);
cmpl(cnt1, 2*stride);
jcc(Assembler::less, SCAN_TO_8_CHAR_INIT);
movdl(vec1, ch);
@@ -6377,10 +6379,8 @@
}
bind(SCAN_TO_8_CHAR);
cmpl(cnt1, stride);
- if (UseAVX >= 2) {
- jcc(Assembler::less, SCAN_TO_CHAR);
- } else {
- jcc(Assembler::less, SCAN_TO_CHAR_LOOP);
+ jcc(Assembler::less, SCAN_TO_CHAR);
+ if (UseAVX < 2) {
movdl(vec1, ch);
pshuflw(vec1, vec1, 0x00);
pshufd(vec1, vec1, 0);
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -34,6 +34,7 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
@@ -1303,6 +1304,97 @@
}
}
+// Registers need to be saved for runtime call
+static Register caller_saved_registers[] = {
+ rcx, rdx, rsi, rdi
+};
+
+// Save caller saved registers except r1 and r2
+static void save_registers_except(MacroAssembler* masm, Register r1, Register r2) {
+ int reg_len = (int)(sizeof(caller_saved_registers) / sizeof(Register));
+ for (int index = 0; index < reg_len; index ++) {
+ Register this_reg = caller_saved_registers[index];
+ if (this_reg != r1 && this_reg != r2) {
+ __ push(this_reg);
+ }
+ }
+}
+
+// Restore caller saved registers except r1 and r2
+static void restore_registers_except(MacroAssembler* masm, Register r1, Register r2) {
+ int reg_len = (int)(sizeof(caller_saved_registers) / sizeof(Register));
+ for (int index = reg_len - 1; index >= 0; index --) {
+ Register this_reg = caller_saved_registers[index];
+ if (this_reg != r1 && this_reg != r2) {
+ __ pop(this_reg);
+ }
+ }
+}
+
+// Pin object, return pinned object or null in rax
+static void gen_pin_object(MacroAssembler* masm,
+ Register thread, VMRegPair reg) {
+ __ block_comment("gen_pin_object {");
+
+ Label is_null;
+ Register tmp_reg = rax;
+ VMRegPair tmp(tmp_reg->as_VMReg());
+ if (reg.first()->is_stack()) {
+ // Load the arg up from the stack
+ simple_move32(masm, reg, tmp);
+ reg = tmp;
+ } else {
+ __ movl(tmp_reg, reg.first()->as_Register());
+ }
+ __ testptr(reg.first()->as_Register(), reg.first()->as_Register());
+ __ jccb(Assembler::equal, is_null);
+
+ // Save registers that may be used by runtime call
+ Register arg = reg.first()->is_Register() ? reg.first()->as_Register() : noreg;
+ save_registers_except(masm, arg, thread);
+
+ __ call_VM_leaf(
+ CAST_FROM_FN_PTR(address, SharedRuntime::pin_object),
+ thread, reg.first()->as_Register());
+
+ // Restore saved registers
+ restore_registers_except(masm, arg, thread);
+
+ __ bind(is_null);
+ __ block_comment("} gen_pin_object");
+}
+
+// Unpin object
+static void gen_unpin_object(MacroAssembler* masm,
+ Register thread, VMRegPair reg) {
+ __ block_comment("gen_unpin_object {");
+ Label is_null;
+
+ // temp register
+ __ push(rax);
+ Register tmp_reg = rax;
+ VMRegPair tmp(tmp_reg->as_VMReg());
+
+ simple_move32(masm, reg, tmp);
+
+ __ testptr(rax, rax);
+ __ jccb(Assembler::equal, is_null);
+
+ // Save registers that may be used by runtime call
+ Register arg = reg.first()->is_Register() ? reg.first()->as_Register() : noreg;
+ save_registers_except(masm, arg, thread);
+
+ __ call_VM_leaf(
+ CAST_FROM_FN_PTR(address, SharedRuntime::unpin_object),
+ thread, rax);
+
+ // Restore saved registers
+ restore_registers_except(masm, arg, thread);
+ __ bind(is_null);
+ __ pop(rax);
+ __ block_comment("} gen_unpin_object");
+}
+
// Check GCLocker::needs_gc and enter the runtime if it's true. This
// keeps a new JNI critical region from starting until a GC has been
// forced. Save down any oops in registers and describe them in an
@@ -1836,7 +1928,7 @@
__ get_thread(thread);
- if (is_critical_native) {
+ if (is_critical_native && !Universe::heap()->supports_object_pinning()) {
check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
oop_handle_offset, oop_maps, in_regs, in_sig_bt);
}
@@ -1874,6 +1966,11 @@
//
OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
+ // Inbound arguments that need to be pinned for critical natives
+ GrowableArray<int> pinned_args(total_in_args);
+ // Current stack slot for storing register based array argument
+ int pinned_slot = oop_handle_offset;
+
// Mark location of rbp,
// map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, rbp->as_VMReg());
@@ -1885,7 +1982,28 @@
switch (in_sig_bt[i]) {
case T_ARRAY:
if (is_critical_native) {
- unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
+ VMRegPair in_arg = in_regs[i];
+ if (Universe::heap()->supports_object_pinning()) {
+ // gen_pin_object handles save and restore
+ // of any clobbered registers
+ gen_pin_object(masm, thread, in_arg);
+ pinned_args.append(i);
+
+ // rax has pinned array
+ VMRegPair result_reg(rax->as_VMReg());
+ if (!in_arg.first()->is_stack()) {
+ assert(pinned_slot <= stack_slots, "overflow");
+ simple_move32(masm, result_reg, VMRegImpl::stack2reg(pinned_slot));
+ pinned_slot += VMRegImpl::slots_per_word;
+ } else {
+ // Write back pinned value, it will be used to unpin this argument
+ __ movptr(Address(rbp, reg2offset_in(in_arg.first())), result_reg.first()->as_Register());
+ }
+ // We have the array in register, use it
+ in_arg = result_reg;
+ }
+
+ unpack_array_argument(masm, in_arg, in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
c_arg++;
break;
}
@@ -2078,6 +2196,26 @@
default : ShouldNotReachHere();
}
+ // unpin pinned arguments
+ pinned_slot = oop_handle_offset;
+ if (pinned_args.length() > 0) {
+ // save return value that may be overwritten otherwise.
+ save_native_result(masm, ret_type, stack_slots);
+ for (int index = 0; index < pinned_args.length(); index ++) {
+ int i = pinned_args.at(index);
+ assert(pinned_slot <= stack_slots, "overflow");
+ if (!in_regs[i].first()->is_stack()) {
+ int offset = pinned_slot * VMRegImpl::stack_slot_size;
+ __ movl(in_regs[i].first()->as_Register(), Address(rsp, offset));
+ pinned_slot += VMRegImpl::slots_per_word;
+ }
+ // gen_pin_object handles save and restore
+ // of any other clobbered registers
+ gen_unpin_object(masm, thread, in_regs[i]);
+ }
+ restore_native_result(masm, ret_type, stack_slots);
+ }
+
// Switch thread to "native transition" state before reading the synchronization state.
// This additional state is necessary because reading and testing the synchronization
// state is not atomic w.r.t. GC, as this scenario demonstrates:
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -41,6 +41,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/compiledICHolder.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
--- a/src/hotspot/os/aix/os_aix.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/os/aix/os_aix.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -2643,8 +2643,24 @@
60 // 11 CriticalPriority
};
+static int prio_init() {
+ if (ThreadPriorityPolicy == 1) {
+ if (geteuid() != 0) {
+ if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
+ warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \
+ "e.g., being the root user. If the necessary permission is not " \
+ "possessed, changes to priority will be silently ignored.");
+ }
+ }
+ }
+ if (UseCriticalJavaThreadPriority) {
+ os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
+ }
+ return 0;
+}
+
OSReturn os::set_native_priority(Thread* thread, int newpri) {
- if (!UseThreadPriorities) return OS_OK;
+ if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;
pthread_t thr = thread->osthread()->pthread_id();
int policy = SCHED_OTHER;
struct sched_param param;
@@ -2659,7 +2675,7 @@
}
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
- if (!UseThreadPriorities) {
+ if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {
*priority_ptr = java_to_os_priority[NormPriority];
return OS_OK;
}
@@ -2756,7 +2772,7 @@
os::SuspendResume::State state = osthread->sr.suspended();
if (state == os::SuspendResume::SR_SUSPENDED) {
sigset_t suspend_set; // signals for sigsuspend()
-
+ sigemptyset(&suspend_set);
// get current set of blocked signals and unblock resume signal
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
sigdelset(&suspend_set, SR_signum);
@@ -3042,6 +3058,7 @@
// try to honor the signal mask
sigset_t oset;
+ sigemptyset(&oset);
pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
// call into the chained handler
@@ -3052,7 +3069,7 @@
}
// restore the signal mask
- pthread_sigmask(SIG_SETMASK, &oset, 0);
+ pthread_sigmask(SIG_SETMASK, &oset, NULL);
}
// Tell jvm's signal handler the signal is taken care of.
return true;
@@ -3568,6 +3585,9 @@
}
}
+ // initialize thread priority policy
+ prio_init();
+
return JNI_OK;
}
@@ -4009,7 +4029,7 @@
void os::pause() {
char filename[MAX_PATH];
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
- jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+ jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
} else {
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
}
--- a/src/hotspot/os/bsd/os_bsd.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/os/bsd/os_bsd.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -3671,7 +3671,7 @@
void os::pause() {
char filename[MAX_PATH];
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
- jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+ jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
} else {
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
}
--- a/src/hotspot/os/solaris/os_solaris.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/os/solaris/os_solaris.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -4428,7 +4428,7 @@
void os::pause() {
char filename[MAX_PATH];
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
- jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+ jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
} else {
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
}
--- a/src/hotspot/os/windows/os_windows.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/os/windows/os_windows.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -4975,7 +4975,7 @@
void os::pause() {
char filename[MAX_PATH];
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
- jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+ jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
} else {
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
}
--- a/src/hotspot/share/aot/aotCodeHeap.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -37,6 +37,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/universe.hpp"
#include "oops/compressedOops.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/aot/aotCompiledMethod.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "compiler/compilerOracle.hpp"
#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -33,13 +33,13 @@
#include "ci/ciKlass.hpp"
#include "ci/ciMemberName.hpp"
#include "ci/ciUtilities.inline.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/bytecode.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/sharedRuntime.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/bitMap.inline.hpp"
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -36,6 +36,7 @@
#include "ci/ciUtilities.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/c1/barrierSetC1.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
--- a/src/hotspot/share/c1/c1_Runtime1.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -37,6 +37,7 @@
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
#include "code/vtableStubs.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/c1/barrierSetC1.hpp"
@@ -55,7 +56,6 @@
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/c1/c1_ValueStack.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/c1/c1_ValueStack.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -42,31 +42,21 @@
verify();
}
-
ValueStack::ValueStack(ValueStack* copy_from, Kind kind, int bci)
: _scope(copy_from->scope())
, _caller_state(copy_from->caller_state())
, _bci(bci)
, _kind(kind)
- , _locals()
- , _stack()
+ , _locals(copy_from->locals_size_for_copy(kind))
+ , _stack(copy_from->stack_size_for_copy(kind))
, _locks(copy_from->locks_size() == 0 ? NULL : new Values(copy_from->locks_size()))
{
assert(kind != EmptyExceptionState || !Compilation::current()->env()->should_retain_local_variables(), "need locals");
if (kind != EmptyExceptionState) {
- // only allocate space if we need to copy the locals-array
- _locals = Values(copy_from->locals_size());
_locals.appendAll(©_from->_locals);
}
if (kind != ExceptionState && kind != EmptyExceptionState) {
- if (kind == Parsing) {
- // stack will be modified, so reserve enough space to avoid resizing
- _stack = Values(scope()->method()->max_stack());
- } else {
- // stack will not be modified, so do not waste space
- _stack = Values(copy_from->stack_size());
- }
_stack.appendAll(©_from->_stack);
}
@@ -77,6 +67,25 @@
verify();
}
+int ValueStack::locals_size_for_copy(Kind kind) const {
+ if (kind != EmptyExceptionState) {
+ return locals_size();
+ }
+ return 0;
+}
+
+int ValueStack::stack_size_for_copy(Kind kind) const {
+ if (kind != ExceptionState && kind != EmptyExceptionState) {
+ if (kind == Parsing) {
+ // stack will be modified, so reserve enough space to avoid resizing
+ return scope()->method()->max_stack();
+ } else {
+ // stack will not be modified, so do not waste space
+ return stack_size();
+ }
+ }
+ return 0;
+}
bool ValueStack::is_same(ValueStack* s) {
if (scope() != s->scope()) return false;
--- a/src/hotspot/share/c1/c1_ValueStack.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/c1/c1_ValueStack.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -65,6 +65,8 @@
// for simplified copying
ValueStack(ValueStack* copy_from, Kind kind, int bci);
+ int locals_size_for_copy(Kind kind) const;
+ int stack_size_for_copy(Kind kind) const;
public:
// creation
ValueStack(IRScope* scope, ValueStack* caller_state);
--- a/src/hotspot/share/ci/ciMetadata.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/ci/ciMetadata.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -51,7 +51,6 @@
virtual bool is_metadata() const { return true; }
virtual bool is_type() const { return false; }
- virtual bool is_cpcache() const { return false; }
virtual bool is_return_address() const { return false; }
virtual bool is_method() const { return false; }
virtual bool is_method_data() const { return false; }
--- a/src/hotspot/share/classfile/classLoader.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/classfile/classLoader.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -57,7 +57,6 @@
#include "oops/symbol.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
--- a/src/hotspot/share/classfile/javaClasses.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -384,13 +384,17 @@
}
jstring js = NULL;
- { JavaThread* thread = (JavaThread*)THREAD;
- assert(thread->is_Java_thread(), "must be java thread");
+ {
+ assert(THREAD->is_Java_thread(), "must be java thread");
+ JavaThread* thread = (JavaThread*)THREAD;
HandleMark hm(thread);
ThreadToNativeFromVM ttn(thread);
js = (_to_java_string_fn)(thread->jni_environment(), str);
}
- return Handle(THREAD, JNIHandles::resolve(js));
+
+ Handle native_platform_string(THREAD, JNIHandles::resolve(js));
+ JNIHandles::destroy_local(js); // destroy local JNIHandle.
+ return native_platform_string;
}
// Converts a Java String to a native C string that can be used for
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -905,14 +905,9 @@
return NULL;
}
- const RunTimeSharedClassInfo* record = find_record(&_unregistered_dictionary, class_name);
+ const RunTimeSharedClassInfo* record = find_record(&_unregistered_dictionary, &_dynamic_unregistered_dictionary, class_name);
if (record == NULL) {
- if (DynamicArchive::is_mapped()) {
- record = find_record(&_dynamic_unregistered_dictionary, class_name);
- }
- if (record == NULL) {
- return NULL;
- }
+ return NULL;
}
int clsfile_size = cfs->length();
@@ -1412,29 +1407,34 @@
}
const RunTimeSharedClassInfo*
-SystemDictionaryShared::find_record(RunTimeSharedDictionary* dict, Symbol* name) {
- if (UseSharedSpaces) {
- unsigned int hash = primitive_hash<Symbol*>(name);
- return dict->lookup(name, hash, 0);
- } else {
+SystemDictionaryShared::find_record(RunTimeSharedDictionary* static_dict, RunTimeSharedDictionary* dynamic_dict, Symbol* name) {
+ if (!UseSharedSpaces || !name->is_shared()) {
+ // The names of all shared classes must also be a shared Symbol.
return NULL;
}
+
+ unsigned int hash = primitive_hash<Symbol*>(name);
+ const RunTimeSharedClassInfo* record = NULL;
+ if (!MetaspaceShared::is_shared_dynamic(name)) {
+ // The names of all shared classes in the static dict must also be in the
+ // static archive
+ record = static_dict->lookup(name, hash, 0);
+ }
+
+ if (record == NULL && DynamicArchive::is_mapped()) {
+ record = dynamic_dict->lookup(name, hash, 0);
+ }
+
+ return record;
}
InstanceKlass* SystemDictionaryShared::find_builtin_class(Symbol* name) {
- const RunTimeSharedClassInfo* record = find_record(&_builtin_dictionary, name);
- if (record) {
+ const RunTimeSharedClassInfo* record = find_record(&_builtin_dictionary, &_dynamic_builtin_dictionary, name);
+ if (record != NULL) {
return record->_klass;
+ } else {
+ return NULL;
}
-
- if (DynamicArchive::is_mapped()) {
- record = find_record(&_dynamic_builtin_dictionary, name);
- if (record) {
- return record->_klass;
- }
- }
-
- return NULL;
}
void SystemDictionaryShared::update_shared_entry(InstanceKlass* k, int id) {
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -223,7 +223,9 @@
public:
static InstanceKlass* find_builtin_class(Symbol* class_name);
- static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* dict, Symbol* name);
+ static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* static_dict,
+ RunTimeSharedDictionary* dynamic_dict,
+ Symbol* name);
static bool has_platform_or_app_classes();
--- a/src/hotspot/share/classfile/verificationType.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/classfile/verificationType.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -28,6 +28,7 @@
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
#include "logging/log.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/handles.inline.hpp"
VerificationType VerificationType::from_tag(u1 tag) {
--- a/src/hotspot/share/code/codeCache.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/code/codeCache.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -33,6 +33,7 @@
#include "code/icBuffer.hpp"
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "jfr/jfrEvents.hpp"
#include "logging/log.hpp"
@@ -46,7 +47,6 @@
#include "oops/oop.inline.hpp"
#include "oops/verifyOopClosure.hpp"
#include "runtime/arguments.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/compilationPolicy.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,506 @@
+/*
+ * 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
+ * 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/classLoaderDataGraph.inline.hpp"
+#include "code/compiledIC.hpp"
+#include "code/nmethod.hpp"
+#include "code/scopeDesc.hpp"
+#include "compiler/compilationPolicy.hpp"
+#include "compiler/tieredThresholdPolicy.hpp"
+#include "interpreter/interpreter.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/methodData.hpp"
+#include "oops/method.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "prims/nativeLookup.hpp"
+#include "runtime/frame.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/vframe.hpp"
+#include "runtime/vmOperations.hpp"
+#include "utilities/events.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#ifdef COMPILER1
+#include "c1/c1_Compiler.hpp"
+#endif
+#ifdef COMPILER2
+#include "opto/c2compiler.hpp"
+#endif
+
+CompilationPolicy* CompilationPolicy::_policy;
+
+// Determine compilation policy based on command line argument
+void compilationPolicy_init() {
+ #ifdef TIERED
+ if (TieredCompilation) {
+ CompilationPolicy::set_policy(new TieredThresholdPolicy());
+ } else {
+ CompilationPolicy::set_policy(new SimpleCompPolicy());
+ }
+ #else
+ CompilationPolicy::set_policy(new SimpleCompPolicy());
+ #endif
+
+ CompilationPolicy::policy()->initialize();
+}
+
+// Returns true if m must be compiled before executing it
+// This is intended to force compiles for methods (usually for
+// debugging) that would otherwise be interpreted for some reason.
+bool CompilationPolicy::must_be_compiled(const methodHandle& m, int comp_level) {
+ // Don't allow Xcomp to cause compiles in replay mode
+ if (ReplayCompiles) return false;
+
+ if (m->has_compiled_code()) return false; // already compiled
+ if (!can_be_compiled(m, comp_level)) return false;
+
+ return !UseInterpreter || // must compile all methods
+ (UseCompiler && AlwaysCompileLoopMethods && m->has_loops() && CompileBroker::should_compile_new_jobs()); // eagerly compile loop methods
+}
+
+void CompilationPolicy::compile_if_required(const methodHandle& selected_method, TRAPS) {
+ if (must_be_compiled(selected_method)) {
+ // This path is unusual, mostly used by the '-Xcomp' stress test mode.
+
+ // Note: with several active threads, the must_be_compiled may be true
+ // while can_be_compiled is false; remove assert
+ // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile");
+ if (!THREAD->can_call_java() || THREAD->is_Compiler_thread()) {
+ // don't force compilation, resolve was on behalf of compiler
+ return;
+ }
+ if (selected_method->method_holder()->is_not_initialized()) {
+ // 'is_not_initialized' means not only '!is_initialized', but also that
+ // initialization has not been started yet ('!being_initialized')
+ // Do not force compilation of methods in uninitialized classes.
+ // Note that doing this would throw an assert later,
+ // in CompileBroker::compile_method.
+ // We sometimes use the link resolver to do reflective lookups
+ // even before classes are initialized.
+ return;
+ }
+ CompileBroker::compile_method(selected_method, InvocationEntryBci,
+ CompilationPolicy::policy()->initial_compile_level(),
+ methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
+ }
+}
+
+// Returns true if m is allowed to be compiled
+bool CompilationPolicy::can_be_compiled(const methodHandle& m, int comp_level) {
+ // allow any levels for WhiteBox
+ assert(WhiteBoxAPI || comp_level == CompLevel_all || is_compile(comp_level), "illegal compilation level");
+
+ if (m->is_abstract()) return false;
+ if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false;
+
+ // Math intrinsics should never be compiled as this can lead to
+ // monotonicity problems because the interpreter will prefer the
+ // compiled code to the intrinsic version. This can't happen in
+ // production because the invocation counter can't be incremented
+ // but we shouldn't expose the system to this problem in testing
+ // modes.
+ if (!AbstractInterpreter::can_be_compiled(m)) {
+ return false;
+ }
+ if (comp_level == CompLevel_all) {
+ if (TieredCompilation) {
+ // enough to be compilable at any level for tiered
+ return !m->is_not_compilable(CompLevel_simple) || !m->is_not_compilable(CompLevel_full_optimization);
+ } else {
+ // must be compilable at available level for non-tiered
+ return !m->is_not_compilable(CompLevel_highest_tier);
+ }
+ } else if (is_compile(comp_level)) {
+ return !m->is_not_compilable(comp_level);
+ }
+ return false;
+}
+
+// Returns true if m is allowed to be osr compiled
+bool CompilationPolicy::can_be_osr_compiled(const methodHandle& m, int comp_level) {
+ bool result = false;
+ if (comp_level == CompLevel_all) {
+ if (TieredCompilation) {
+ // enough to be osr compilable at any level for tiered
+ result = !m->is_not_osr_compilable(CompLevel_simple) || !m->is_not_osr_compilable(CompLevel_full_optimization);
+ } else {
+ // must be osr compilable at available level for non-tiered
+ result = !m->is_not_osr_compilable(CompLevel_highest_tier);
+ }
+ } else if (is_compile(comp_level)) {
+ result = !m->is_not_osr_compilable(comp_level);
+ }
+ return (result && can_be_compiled(m, comp_level));
+}
+
+bool CompilationPolicy::is_compilation_enabled() {
+ // NOTE: CompileBroker::should_compile_new_jobs() checks for UseCompiler
+ return CompileBroker::should_compile_new_jobs();
+}
+
+CompileTask* CompilationPolicy::select_task_helper(CompileQueue* compile_queue) {
+ // Remove unloaded methods from the queue
+ for (CompileTask* task = compile_queue->first(); task != NULL; ) {
+ CompileTask* next = task->next();
+ if (task->is_unloaded()) {
+ compile_queue->remove_and_mark_stale(task);
+ }
+ task = next;
+ }
+#if INCLUDE_JVMCI
+ if (UseJVMCICompiler && !BackgroundCompilation) {
+ /*
+ * In blocking compilation mode, the CompileBroker will make
+ * compilations submitted by a JVMCI compiler thread non-blocking. These
+ * compilations should be scheduled after all blocking compilations
+ * to service non-compiler related compilations sooner and reduce the
+ * chance of such compilations timing out.
+ */
+ for (CompileTask* task = compile_queue->first(); task != NULL; task = task->next()) {
+ if (task->is_blocking()) {
+ return task;
+ }
+ }
+ }
+#endif
+ return compile_queue->first();
+}
+
+#ifndef PRODUCT
+void SimpleCompPolicy::trace_osr_completion(nmethod* osr_nm) {
+ if (TraceOnStackReplacement) {
+ if (osr_nm == NULL) tty->print_cr("compilation failed");
+ else tty->print_cr("nmethod " INTPTR_FORMAT, p2i(osr_nm));
+ }
+}
+#endif // !PRODUCT
+
+void SimpleCompPolicy::initialize() {
+ // Setup the compiler thread numbers
+ if (CICompilerCountPerCPU) {
+ // Example: if CICompilerCountPerCPU is true, then we get
+ // max(log2(8)-1,1) = 2 compiler threads on an 8-way machine.
+ // May help big-app startup time.
+ _compiler_count = MAX2(log2_int(os::active_processor_count())-1,1);
+ // Make sure there is enough space in the code cache to hold all the compiler buffers
+ size_t buffer_size = 1;
+#ifdef COMPILER1
+ buffer_size = is_client_compilation_mode_vm() ? Compiler::code_buffer_size() : buffer_size;
+#endif
+#ifdef COMPILER2
+ buffer_size = is_server_compilation_mode_vm() ? C2Compiler::initial_code_buffer_size() : buffer_size;
+#endif
+ int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size;
+ if (_compiler_count > max_count) {
+ // Lower the compiler count such that all buffers fit into the code cache
+ _compiler_count = MAX2(max_count, 1);
+ }
+ FLAG_SET_ERGO(CICompilerCount, _compiler_count);
+ } else {
+ _compiler_count = CICompilerCount;
+ }
+}
+
+// Note: this policy is used ONLY if TieredCompilation is off.
+// compiler_count() behaves the following way:
+// - with TIERED build (with both COMPILER1 and COMPILER2 defined) it should return
+// zero for the c1 compilation levels in server compilation mode runs
+// and c2 compilation levels in client compilation mode runs.
+// - with COMPILER2 not defined it should return zero for c2 compilation levels.
+// - with COMPILER1 not defined it should return zero for c1 compilation levels.
+// - if neither is defined - always return zero.
+int SimpleCompPolicy::compiler_count(CompLevel comp_level) {
+ assert(!TieredCompilation, "This policy should not be used with TieredCompilation");
+ if (COMPILER2_PRESENT(is_server_compilation_mode_vm() && is_c2_compile(comp_level) ||)
+ is_client_compilation_mode_vm() && is_c1_compile(comp_level)) {
+ return _compiler_count;
+ }
+ return 0;
+}
+
+void SimpleCompPolicy::reset_counter_for_invocation_event(const methodHandle& m) {
+ // Make sure invocation and backedge counter doesn't overflow again right away
+ // as would be the case for native methods.
+
+ // BUT also make sure the method doesn't look like it was never executed.
+ // Set carry bit and reduce counter's value to min(count, CompileThreshold/2).
+ MethodCounters* mcs = m->method_counters();
+ assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+ mcs->invocation_counter()->set_carry();
+ mcs->backedge_counter()->set_carry();
+
+ assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
+}
+
+void SimpleCompPolicy::reset_counter_for_back_branch_event(const methodHandle& m) {
+ // Delay next back-branch event but pump up invocation counter to trigger
+ // whole method compilation.
+ MethodCounters* mcs = m->method_counters();
+ assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+ InvocationCounter* i = mcs->invocation_counter();
+ InvocationCounter* b = mcs->backedge_counter();
+
+ // Don't set invocation_counter's value too low otherwise the method will
+ // look like immature (ic < ~5300) which prevents the inlining based on
+ // the type profiling.
+ i->set(i->state(), CompileThreshold);
+ // Don't reset counter too low - it is used to check if OSR method is ready.
+ b->set(b->state(), CompileThreshold / 2);
+}
+
+//
+// CounterDecay
+//
+// Iterates through invocation counters and decrements them. This
+// is done at each safepoint.
+//
+class CounterDecay : public AllStatic {
+ static jlong _last_timestamp;
+ static void do_method(Method* m) {
+ MethodCounters* mcs = m->method_counters();
+ if (mcs != NULL) {
+ mcs->invocation_counter()->decay();
+ }
+ }
+public:
+ static void decay();
+ static bool is_decay_needed() {
+ return (os::javaTimeMillis() - _last_timestamp) > CounterDecayMinIntervalLength;
+ }
+};
+
+jlong CounterDecay::_last_timestamp = 0;
+
+void CounterDecay::decay() {
+ _last_timestamp = os::javaTimeMillis();
+
+ // This operation is going to be performed only at the end of a safepoint
+ // and hence GC's will not be going on, all Java mutators are suspended
+ // at this point and hence SystemDictionary_lock is also not needed.
+ assert(SafepointSynchronize::is_at_safepoint(), "can only be executed at a safepoint");
+ size_t nclasses = ClassLoaderDataGraph::num_instance_classes();
+ size_t classes_per_tick = nclasses * (CounterDecayMinIntervalLength * 1e-3 /
+ CounterHalfLifeTime);
+ for (size_t i = 0; i < classes_per_tick; i++) {
+ InstanceKlass* k = ClassLoaderDataGraph::try_get_next_class();
+ if (k != NULL) {
+ k->methods_do(do_method);
+ }
+ }
+}
+
+// Called at the end of the safepoint
+void SimpleCompPolicy::do_safepoint_work() {
+ if(UseCounterDecay && CounterDecay::is_decay_needed()) {
+ CounterDecay::decay();
+ }
+}
+
+void SimpleCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
+ ScopeDesc* sd = trap_scope;
+ MethodCounters* mcs;
+ InvocationCounter* c;
+ for (; !sd->is_top(); sd = sd->sender()) {
+ mcs = sd->method()->method_counters();
+ if (mcs != NULL) {
+ // Reset ICs of inlined methods, since they can trigger compilations also.
+ mcs->invocation_counter()->reset();
+ }
+ }
+ mcs = sd->method()->method_counters();
+ if (mcs != NULL) {
+ c = mcs->invocation_counter();
+ if (is_osr) {
+ // It was an OSR method, so bump the count higher.
+ c->set(c->state(), CompileThreshold);
+ } else {
+ c->reset();
+ }
+ mcs->backedge_counter()->reset();
+ }
+}
+
+// This method can be called by any component of the runtime to notify the policy
+// that it's recommended to delay the compilation of this method.
+void SimpleCompPolicy::delay_compilation(Method* method) {
+ MethodCounters* mcs = method->method_counters();
+ if (mcs != NULL) {
+ mcs->invocation_counter()->decay();
+ mcs->backedge_counter()->decay();
+ }
+}
+
+void SimpleCompPolicy::disable_compilation(Method* method) {
+ MethodCounters* mcs = method->method_counters();
+ if (mcs != NULL) {
+ mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
+ mcs->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
+ }
+}
+
+CompileTask* SimpleCompPolicy::select_task(CompileQueue* compile_queue) {
+ return select_task_helper(compile_queue);
+}
+
+bool SimpleCompPolicy::is_mature(Method* method) {
+ MethodData* mdo = method->method_data();
+ assert(mdo != NULL, "Should be");
+ uint current = mdo->mileage_of(method);
+ uint initial = mdo->creation_mileage();
+ if (current < initial)
+ return true; // some sort of overflow
+ uint target;
+ if (ProfileMaturityPercentage <= 0)
+ target = (uint) -ProfileMaturityPercentage; // absolute value
+ else
+ target = (uint)( (ProfileMaturityPercentage * CompileThreshold) / 100 );
+ return (current >= initial + target);
+}
+
+nmethod* SimpleCompPolicy::event(const methodHandle& method, const methodHandle& inlinee, int branch_bci,
+ int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
+ assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
+ NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
+ if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
+ // If certain JVMTI events (e.g. frame pop event) are requested then the
+ // thread is forced to remain in interpreted code. This is
+ // implemented partly by a check in the run_compiled_code
+ // section of the interpreter whether we should skip running
+ // compiled code, and partly by skipping OSR compiles for
+ // interpreted-only threads.
+ if (bci != InvocationEntryBci) {
+ reset_counter_for_back_branch_event(method);
+ return NULL;
+ }
+ }
+ if (ReplayCompiles) {
+ // Don't trigger other compiles in testing mode
+ if (bci == InvocationEntryBci) {
+ reset_counter_for_invocation_event(method);
+ } else {
+ reset_counter_for_back_branch_event(method);
+ }
+ return NULL;
+ }
+
+ if (bci == InvocationEntryBci) {
+ // when code cache is full, compilation gets switched off, UseCompiler
+ // is set to false
+ if (!method->has_compiled_code() && UseCompiler) {
+ method_invocation_event(method, thread);
+ } else {
+ // Force counter overflow on method entry, even if no compilation
+ // happened. (The method_invocation_event call does this also.)
+ reset_counter_for_invocation_event(method);
+ }
+ // compilation at an invocation overflow no longer goes and retries test for
+ // compiled method. We always run the loser of the race as interpreted.
+ // so return NULL
+ return NULL;
+ } else {
+ // counter overflow in a loop => try to do on-stack-replacement
+ nmethod* osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
+ NOT_PRODUCT(trace_osr_request(method, osr_nm, bci));
+ // when code cache is full, we should not compile any more...
+ if (osr_nm == NULL && UseCompiler) {
+ method_back_branch_event(method, bci, thread);
+ osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
+ }
+ if (osr_nm == NULL) {
+ reset_counter_for_back_branch_event(method);
+ return NULL;
+ }
+ return osr_nm;
+ }
+ return NULL;
+}
+
+#ifndef PRODUCT
+void SimpleCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) {
+ if (TraceInvocationCounterOverflow) {
+ MethodCounters* mcs = m->method_counters();
+ assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+ InvocationCounter* ic = mcs->invocation_counter();
+ InvocationCounter* bc = mcs->backedge_counter();
+ ResourceMark rm;
+ if (bci == InvocationEntryBci) {
+ tty->print("comp-policy cntr ovfl @ %d in entry of ", bci);
+ } else {
+ tty->print("comp-policy cntr ovfl @ %d in loop of ", bci);
+ }
+ m->print_value();
+ tty->cr();
+ ic->print();
+ bc->print();
+ if (ProfileInterpreter) {
+ if (bci != InvocationEntryBci) {
+ MethodData* mdo = m->method_data();
+ if (mdo != NULL) {
+ ProfileData *pd = mdo->bci_to_data(branch_bci);
+ if (pd == NULL) {
+ tty->print_cr("back branch count = N/A (missing ProfileData)");
+ } else {
+ tty->print_cr("back branch count = %d", pd->as_JumpData()->taken());
+ }
+ }
+ }
+ }
+ }
+}
+
+void SimpleCompPolicy::trace_osr_request(const methodHandle& method, nmethod* osr, int bci) {
+ if (TraceOnStackReplacement) {
+ ResourceMark rm;
+ tty->print(osr != NULL ? "Reused OSR entry for " : "Requesting OSR entry for ");
+ method->print_short_name(tty);
+ tty->print_cr(" at bci %d", bci);
+ }
+}
+#endif // !PRODUCT
+
+void SimpleCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) {
+ const int comp_level = CompLevel_highest_tier;
+ const int hot_count = m->invocation_count();
+ reset_counter_for_invocation_event(m);
+
+ if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
+ CompiledMethod* nm = m->code();
+ if (nm == NULL ) {
+ CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, CompileTask::Reason_InvocationCount, thread);
+ }
+ }
+}
+
+void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
+ const int comp_level = CompLevel_highest_tier;
+ const int hot_count = m->backedge_count();
+
+ if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
+ CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, thread);
+ NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/compilationPolicy.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,113 @@
+/*
+ * 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
+ * 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_COMPILER_COMPILATIONPOLICY_HPP
+#define SHARE_COMPILER_COMPILATIONPOLICY_HPP
+
+#include "code/nmethod.hpp"
+#include "compiler/compileBroker.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/vmOperations.hpp"
+#include "utilities/growableArray.hpp"
+
+// The CompilationPolicy selects which method (if any) should be compiled.
+// It also decides which methods must always be compiled (i.e., are never
+// interpreted).
+class CompileTask;
+class CompileQueue;
+
+class CompilationPolicy : public CHeapObj<mtCompiler> {
+ static CompilationPolicy* _policy;
+
+ // m must be compiled before executing it
+ static bool must_be_compiled(const methodHandle& m, int comp_level = CompLevel_all);
+
+public:
+ // If m must_be_compiled then request a compilation from the CompileBroker.
+ // This supports the -Xcomp option.
+ static void compile_if_required(const methodHandle& m, TRAPS);
+
+ // m is allowed to be compiled
+ static bool can_be_compiled(const methodHandle& m, int comp_level = CompLevel_all);
+ // m is allowed to be osr compiled
+ static bool can_be_osr_compiled(const methodHandle& m, int comp_level = CompLevel_all);
+ static bool is_compilation_enabled();
+ static void set_policy(CompilationPolicy* policy) { _policy = policy; }
+ static CompilationPolicy* policy() { return _policy; }
+
+ static CompileTask* select_task_helper(CompileQueue* compile_queue);
+
+ // Return initial compile level that is used with Xcomp
+ virtual CompLevel initial_compile_level() = 0;
+ virtual int compiler_count(CompLevel comp_level) = 0;
+ // main notification entry, return a pointer to an nmethod if the OSR is required,
+ // returns NULL otherwise.
+ virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) = 0;
+ // safepoint() is called at the end of the safepoint
+ virtual void do_safepoint_work() = 0;
+ // reprofile request
+ virtual void reprofile(ScopeDesc* trap_scope, bool is_osr) = 0;
+ // delay_compilation(method) can be called by any component of the runtime to notify the policy
+ // that it's recommended to delay the compilation of this method.
+ virtual void delay_compilation(Method* method) = 0;
+ // disable_compilation() is called whenever the runtime decides to disable compilation of the
+ // specified method.
+ virtual void disable_compilation(Method* method) = 0;
+ // Select task is called by CompileBroker. The queue is guaranteed to have at least one
+ // element and is locked. The function should select one and return it.
+ virtual CompileTask* select_task(CompileQueue* compile_queue) = 0;
+ // Tell the runtime if we think a given method is adequately profiled.
+ virtual bool is_mature(Method* method) = 0;
+ // Do policy initialization
+ virtual void initialize() = 0;
+ virtual bool should_not_inline(ciEnv* env, ciMethod* method) { return false; }
+};
+
+// A simple compilation policy.
+class SimpleCompPolicy : public CompilationPolicy {
+ int _compiler_count;
+ private:
+ static void trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci);
+ static void trace_osr_request(const methodHandle& method, nmethod* osr, int bci);
+ static void trace_osr_completion(nmethod* osr_nm);
+ void reset_counter_for_invocation_event(const methodHandle& method);
+ void reset_counter_for_back_branch_event(const methodHandle& method);
+ void method_invocation_event(const methodHandle& m, JavaThread* thread);
+ void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
+ public:
+ SimpleCompPolicy() : _compiler_count(0) { }
+ virtual CompLevel initial_compile_level() { return CompLevel_highest_tier; }
+ virtual int compiler_count(CompLevel comp_level);
+ virtual void do_safepoint_work();
+ virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
+ virtual void delay_compilation(Method* method);
+ virtual void disable_compilation(Method* method);
+ virtual bool is_mature(Method* method);
+ virtual void initialize();
+ virtual CompileTask* select_task(CompileQueue* compile_queue);
+ virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
+};
+
+
+#endif // SHARE_COMPILER_COMPILATIONPOLICY_HPP
--- a/src/hotspot/share/compiler/compileBroker.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/compiler/compileBroker.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -30,6 +30,7 @@
#include "code/codeCache.hpp"
#include "code/codeHeapState.hpp"
#include "code/dependencyContext.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compilerOracle.hpp"
@@ -48,7 +49,6 @@
#include "prims/whitebox.hpp"
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
--- a/src/hotspot/share/compiler/oopMap.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/compiler/oopMap.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -48,29 +48,25 @@
// OopMapStream
-OopMapStream::OopMapStream(OopMap* oop_map, int oop_types_mask) {
+OopMapStream::OopMapStream(OopMap* oop_map) {
_stream = new CompressedReadStream(oop_map->write_stream()->buffer());
- _mask = oop_types_mask;
_size = oop_map->omv_count();
_position = 0;
_valid_omv = false;
}
-OopMapStream::OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask) {
+OopMapStream::OopMapStream(const ImmutableOopMap* oop_map) {
_stream = new CompressedReadStream(oop_map->data_addr());
- _mask = oop_types_mask;
_size = oop_map->count();
_position = 0;
_valid_omv = false;
}
void OopMapStream::find_next() {
- while(_position++ < _size) {
+ if (_position++ < _size) {
_omv.read_from(_stream);
- if(((int)_omv.type() & _mask) > 0) {
- _valid_omv = true;
- return;
- }
+ _valid_omv = true;
+ return;
}
_valid_omv = false;
}
@@ -140,16 +136,7 @@
assert( _locs_used[reg->value()] == OopMapValue::unused_value, "cannot insert twice" );
debug_only( _locs_used[reg->value()] = x; )
- OopMapValue o(reg, x);
-
- if(x == OopMapValue::callee_saved_value) {
- // This can never be a stack location, so we don't need to transform it.
- assert(optional->is_reg(), "Trying to callee save a stack location");
- o.set_content_reg(optional);
- } else if(x == OopMapValue::derived_oop_value) {
- o.set_content_reg(optional);
- }
-
+ OopMapValue o(reg, x, optional);
o.write_on(write_stream());
increment_count();
}
@@ -160,11 +147,6 @@
}
-void OopMap::set_value(VMReg reg) {
- // At this time, we don't need value entries in our OopMap.
-}
-
-
void OopMap::set_narrowoop(VMReg reg) {
set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
}
@@ -328,7 +310,7 @@
// changed before derived pointer offset has been collected)
OopMapValue omv;
{
- OopMapStream oms(map,OopMapValue::derived_oop_value);
+ OopMapStream oms(map);
if (!oms.is_done()) {
#ifndef TIERED
COMPILER1_PRESENT(ShouldNotReachHere();)
@@ -340,27 +322,28 @@
#endif // !TIERED
do {
omv = oms.current();
- oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
- guarantee(loc != NULL, "missing saved register");
- oop *derived_loc = loc;
- oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
- // Ignore NULL oops and decoded NULL narrow oops which
- // equal to CompressedOops::base() when a narrow oop
- // implicit null check is used in compiled code.
- // The narrow_oop_base could be NULL or be the address
- // of the page below heap depending on compressed oops mode.
- if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
- derived_oop_fn(base_loc, derived_loc);
+ if (omv.type() == OopMapValue::derived_oop_value) {
+ oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
+ guarantee(loc != NULL, "missing saved register");
+ oop *derived_loc = loc;
+ oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
+ // Ignore NULL oops and decoded NULL narrow oops which
+ // equal to CompressedOops::base() when a narrow oop
+ // implicit null check is used in compiled code.
+ // The narrow_oop_base could be NULL or be the address
+ // of the page below heap depending on compressed oops mode.
+ if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
+ derived_oop_fn(base_loc, derived_loc);
+ }
}
oms.next();
} while (!oms.is_done());
}
}
- // We want coop and oop oop_types
- int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
{
- for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
+ // We want coop and oop oop_types
+ for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
// It should be an error if no location can be found for a
@@ -436,12 +419,14 @@
assert(map != NULL, "no ptr map found");
DEBUG_ONLY(int nof_callee = 0;)
- for (OopMapStream oms(map, OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
+ for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
OopMapValue omv = oms.current();
- VMReg reg = omv.content_reg();
- oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
- reg_map->set_location(reg, (address) loc);
- DEBUG_ONLY(nof_callee++;)
+ if (omv.type() == OopMapValue::callee_saved_value) {
+ VMReg reg = omv.content_reg();
+ oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
+ reg_map->set_location(reg, (address) loc);
+ DEBUG_ONLY(nof_callee++;)
+ }
}
// Check that runtime stubs save all callee-saved registers
@@ -452,25 +437,6 @@
#endif // COMPILER2
}
-//=============================================================================
-// Non-Product code
-
-#ifndef PRODUCT
-
-bool ImmutableOopMap::has_derived_pointer() const {
-#if !defined(TIERED) && !INCLUDE_JVMCI
- COMPILER1_PRESENT(return false);
-#endif // !TIERED
-#if COMPILER2_OR_JVMCI
- OopMapStream oms(this,OopMapValue::derived_oop_value);
- return oms.is_done();
-#else
- return false;
-#endif // COMPILER2_OR_JVMCI
-}
-
-#endif //PRODUCT
-
// Printing code is present in product build for -XX:+PrintAssembly.
static
--- a/src/hotspot/share/compiler/oopMap.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/compiler/oopMap.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -53,7 +53,7 @@
public:
// Constants
- enum { type_bits = 4,
+ enum { type_bits = 2,
register_bits = BitsPerShort - type_bits };
enum { type_shift = 0,
@@ -64,19 +64,41 @@
register_mask = right_n_bits(register_bits),
register_mask_in_place = register_mask << register_shift };
- enum oop_types { // must fit in type_bits
- unused_value =0, // powers of 2, for masking OopMapStream
- oop_value = 1,
- narrowoop_value = 2,
- callee_saved_value = 4,
- derived_oop_value= 8 };
+ enum oop_types {
+ oop_value,
+ narrowoop_value,
+ callee_saved_value,
+ derived_oop_value,
+ unused_value = -1 // Only used as a sentinel value
+ };
// Constructors
OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
- OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg, t); set_content_reg(VMRegImpl::Bad()); }
- OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg, t); set_content_reg(reg2); }
- OopMapValue (CompressedReadStream* stream) { read_from(stream); }
+ OopMapValue (VMReg reg, oop_types t, VMReg reg2) {
+ set_reg_type(reg, t);
+ set_content_reg(reg2);
+ }
+
+ private:
+ void set_reg_type(VMReg p, oop_types t) {
+ set_value((p->value() << register_shift) | t);
+ assert(reg() == p, "sanity check" );
+ assert(type() == t, "sanity check" );
+ }
+ void set_content_reg(VMReg r) {
+ if (is_callee_saved()) {
+ // This can never be a stack location, so we don't need to transform it.
+ assert(r->is_reg(), "Trying to callee save a stack location");
+ } else if (is_derived_oop()) {
+ assert (r->is_valid(), "must have a valid VMReg");
+ } else {
+ assert (!r->is_valid(), "valid VMReg not allowed");
+ }
+ _content_reg = r->value();
+ }
+
+ public:
// Archiving
void write_on(CompressedWriteStream* stream) {
stream->write_int(value());
@@ -94,15 +116,10 @@
// Querying
bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; }
- bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
+ bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
- void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
- void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
- void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
- void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }
-
VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); }
@@ -110,15 +127,7 @@
return (p->value() == (p->value() & register_mask));
}
- void set_reg_type(VMReg p, oop_types t) {
- set_value((p->value() << register_shift) | t);
- assert(reg() == p, "sanity check" );
- assert(type() == t, "sanity check" );
- }
-
-
VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); }
- void set_content_reg(VMReg r) { _content_reg = r->value(); }
// Physical location queries
bool is_register_loc() { return reg()->is_reg(); }
@@ -156,6 +165,8 @@
enum DeepCopyToken { _deep_copy_token };
OopMap(DeepCopyToken, OopMap* source); // used only by deep_copy
+ void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
+
public:
OopMap(int frame_size, int arg_count);
@@ -173,19 +184,14 @@
// frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
// slots to hold 4-byte values like ints and floats in the LP64 build.
void set_oop ( VMReg local);
- void set_value( VMReg local);
void set_narrowoop(VMReg local);
- void set_dead ( VMReg local);
void set_callee_saved( VMReg local, VMReg caller_machine_register );
void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
- void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
int heap_size() const;
void copy_data_to(address addr) const;
OopMap* deep_copy();
- bool has_derived_pointer() const PRODUCT_RETURN0;
-
bool legal_vm_reg_name(VMReg local) {
return OopMapValue::legal_vm_reg_name(local);
}
@@ -269,7 +275,6 @@
public:
ImmutableOopMap(const OopMap* oopmap);
- bool has_derived_pointer() const PRODUCT_RETURN0;
int count() const { return _count; }
#ifdef ASSERT
int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
@@ -334,7 +339,6 @@
class OopMapStream : public StackObj {
private:
CompressedReadStream* _stream;
- int _mask;
int _size;
int _position;
bool _valid_omv;
@@ -342,8 +346,8 @@
void find_next();
public:
- OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
- OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
+ OopMapStream(OopMap* oop_map);
+ OopMapStream(const ImmutableOopMap* oop_map);
bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; }
void next() { find_next(); }
OopMapValue current() { return _omv; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,1005 @@
+/*
+ * 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
+ * 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 "compiler/compileBroker.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "compiler/tieredThresholdPolicy.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/safepointVerifiers.hpp"
+#include "code/scopeDesc.hpp"
+#include "oops/method.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
+
+#ifdef TIERED
+
+#include "c1/c1_Compiler.hpp"
+#include "opto/c2compiler.hpp"
+
+template<CompLevel level>
+bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
+ double threshold_scaling;
+ if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
+ scale *= threshold_scaling;
+ }
+ switch(level) {
+ case CompLevel_aot:
+ return (i >= Tier3AOTInvocationThreshold * scale) ||
+ (i >= Tier3AOTMinInvocationThreshold * scale && i + b >= Tier3AOTCompileThreshold * scale);
+ case CompLevel_none:
+ case CompLevel_limited_profile:
+ return (i >= Tier3InvocationThreshold * scale) ||
+ (i >= Tier3MinInvocationThreshold * scale && i + b >= Tier3CompileThreshold * scale);
+ case CompLevel_full_profile:
+ return (i >= Tier4InvocationThreshold * scale) ||
+ (i >= Tier4MinInvocationThreshold * scale && i + b >= Tier4CompileThreshold * scale);
+ }
+ return true;
+}
+
+template<CompLevel level>
+bool TieredThresholdPolicy::loop_predicate_helper(int i, int b, double scale, Method* method) {
+ double threshold_scaling;
+ if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
+ scale *= threshold_scaling;
+ }
+ switch(level) {
+ case CompLevel_aot:
+ return b >= Tier3AOTBackEdgeThreshold * scale;
+ case CompLevel_none:
+ case CompLevel_limited_profile:
+ return b >= Tier3BackEdgeThreshold * scale;
+ case CompLevel_full_profile:
+ return b >= Tier4BackEdgeThreshold * scale;
+ }
+ return true;
+}
+
+// Simple methods are as good being compiled with C1 as C2.
+// Determine if a given method is such a case.
+bool TieredThresholdPolicy::is_trivial(Method* method) {
+ if (method->is_accessor() ||
+ method->is_constant_getter()) {
+ return true;
+ }
+ return false;
+}
+
+bool TieredThresholdPolicy::should_compile_at_level_simple(Method* method) {
+ if (TieredThresholdPolicy::is_trivial(method)) {
+ return true;
+ }
+#if INCLUDE_JVMCI
+ if (UseJVMCICompiler) {
+ AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization);
+ if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) {
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+CompLevel TieredThresholdPolicy::comp_level(Method* method) {
+ CompiledMethod *nm = method->code();
+ if (nm != NULL && nm->is_in_use()) {
+ return (CompLevel)nm->comp_level();
+ }
+ return CompLevel_none;
+}
+
+void TieredThresholdPolicy::print_counters(const char* prefix, const methodHandle& mh) {
+ int invocation_count = mh->invocation_count();
+ int backedge_count = mh->backedge_count();
+ MethodData* mdh = mh->method_data();
+ int mdo_invocations = 0, mdo_backedges = 0;
+ int mdo_invocations_start = 0, mdo_backedges_start = 0;
+ if (mdh != NULL) {
+ mdo_invocations = mdh->invocation_count();
+ mdo_backedges = mdh->backedge_count();
+ mdo_invocations_start = mdh->invocation_count_start();
+ mdo_backedges_start = mdh->backedge_count_start();
+ }
+ tty->print(" %stotal=%d,%d %smdo=%d(%d),%d(%d)", prefix,
+ invocation_count, backedge_count, prefix,
+ mdo_invocations, mdo_invocations_start,
+ mdo_backedges, mdo_backedges_start);
+ tty->print(" %smax levels=%d,%d", prefix,
+ mh->highest_comp_level(), mh->highest_osr_comp_level());
+}
+
+// Print an event.
+void TieredThresholdPolicy::print_event(EventType type, const methodHandle& mh, const methodHandle& imh,
+ int bci, CompLevel level) {
+ bool inlinee_event = mh() != imh();
+
+ ttyLocker tty_lock;
+ tty->print("%lf: [", os::elapsedTime());
+
+ switch(type) {
+ case CALL:
+ tty->print("call");
+ break;
+ case LOOP:
+ tty->print("loop");
+ break;
+ case COMPILE:
+ tty->print("compile");
+ break;
+ case REMOVE_FROM_QUEUE:
+ tty->print("remove-from-queue");
+ break;
+ case UPDATE_IN_QUEUE:
+ tty->print("update-in-queue");
+ break;
+ case REPROFILE:
+ tty->print("reprofile");
+ break;
+ case MAKE_NOT_ENTRANT:
+ tty->print("make-not-entrant");
+ break;
+ default:
+ tty->print("unknown");
+ }
+
+ tty->print(" level=%d ", level);
+
+ ResourceMark rm;
+ char *method_name = mh->name_and_sig_as_C_string();
+ tty->print("[%s", method_name);
+ if (inlinee_event) {
+ char *inlinee_name = imh->name_and_sig_as_C_string();
+ tty->print(" [%s]] ", inlinee_name);
+ }
+ else tty->print("] ");
+ tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
+ CompileBroker::queue_size(CompLevel_full_optimization));
+
+ print_specific(type, mh, imh, bci, level);
+
+ if (type != COMPILE) {
+ print_counters("", mh);
+ if (inlinee_event) {
+ print_counters("inlinee ", imh);
+ }
+ tty->print(" compilable=");
+ bool need_comma = false;
+ if (!mh->is_not_compilable(CompLevel_full_profile)) {
+ tty->print("c1");
+ need_comma = true;
+ }
+ if (!mh->is_not_osr_compilable(CompLevel_full_profile)) {
+ if (need_comma) tty->print(",");
+ tty->print("c1-osr");
+ need_comma = true;
+ }
+ if (!mh->is_not_compilable(CompLevel_full_optimization)) {
+ if (need_comma) tty->print(",");
+ tty->print("c2");
+ need_comma = true;
+ }
+ if (!mh->is_not_osr_compilable(CompLevel_full_optimization)) {
+ if (need_comma) tty->print(",");
+ tty->print("c2-osr");
+ }
+ tty->print(" status=");
+ if (mh->queued_for_compilation()) {
+ tty->print("in-queue");
+ } else tty->print("idle");
+ }
+ tty->print_cr("]");
+}
+
+void TieredThresholdPolicy::initialize() {
+ int count = CICompilerCount;
+ bool c1_only = TieredStopAtLevel < CompLevel_full_optimization;
+#ifdef _LP64
+ // Turn on ergonomic compiler count selection
+ if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
+ FLAG_SET_DEFAULT(CICompilerCountPerCPU, true);
+ }
+ if (CICompilerCountPerCPU) {
+ // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
+ int log_cpu = log2_int(os::active_processor_count());
+ int loglog_cpu = log2_int(MAX2(log_cpu, 1));
+ count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
+ // Make sure there is enough space in the code cache to hold all the compiler buffers
+ size_t c1_size = Compiler::code_buffer_size();
+ size_t c2_size = C2Compiler::initial_code_buffer_size();
+ size_t buffer_size = c1_only ? c1_size : (c1_size/3 + 2*c2_size/3);
+ int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size;
+ if (count > max_count) {
+ // Lower the compiler count such that all buffers fit into the code cache
+ count = MAX2(max_count, c1_only ? 1 : 2);
+ }
+ FLAG_SET_ERGO(CICompilerCount, count);
+ }
+#else
+ // On 32-bit systems, the number of compiler threads is limited to 3.
+ // On these systems, the virtual address space available to the JVM
+ // is usually limited to 2-4 GB (the exact value depends on the platform).
+ // As the compilers (especially C2) can consume a large amount of
+ // memory, scaling the number of compiler threads with the number of
+ // available cores can result in the exhaustion of the address space
+ /// available to the VM and thus cause the VM to crash.
+ if (FLAG_IS_DEFAULT(CICompilerCount)) {
+ count = 3;
+ FLAG_SET_ERGO(CICompilerCount, count);
+ }
+#endif
+
+ if (c1_only) {
+ // No C2 compiler thread required
+ set_c1_count(count);
+ } else {
+ set_c1_count(MAX2(count / 3, 1));
+ set_c2_count(MAX2(count - c1_count(), 1));
+ }
+ assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
+
+ // Some inlining tuning
+#ifdef X86
+ if (FLAG_IS_DEFAULT(InlineSmallCode)) {
+ FLAG_SET_DEFAULT(InlineSmallCode, 2000);
+ }
+#endif
+
+#if defined SPARC || defined AARCH64
+ if (FLAG_IS_DEFAULT(InlineSmallCode)) {
+ FLAG_SET_DEFAULT(InlineSmallCode, 2500);
+ }
+#endif
+
+ set_increase_threshold_at_ratio();
+ set_start_time(os::javaTimeMillis());
+}
+
+void TieredThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
+ if (!counter->carry() && counter->count() > InvocationCounter::count_limit / 2) {
+ counter->set_carry_flag();
+ }
+}
+
+// Set carry flags on the counters if necessary
+void TieredThresholdPolicy::handle_counter_overflow(Method* method) {
+ MethodCounters *mcs = method->method_counters();
+ if (mcs != NULL) {
+ set_carry_if_necessary(mcs->invocation_counter());
+ set_carry_if_necessary(mcs->backedge_counter());
+ }
+ MethodData* mdo = method->method_data();
+ if (mdo != NULL) {
+ set_carry_if_necessary(mdo->invocation_counter());
+ set_carry_if_necessary(mdo->backedge_counter());
+ }
+}
+
+// Called with the queue locked and with at least one element
+CompileTask* TieredThresholdPolicy::select_task(CompileQueue* compile_queue) {
+ CompileTask *max_blocking_task = NULL;
+ CompileTask *max_task = NULL;
+ Method* max_method = NULL;
+ jlong t = os::javaTimeMillis();
+ // Iterate through the queue and find a method with a maximum rate.
+ for (CompileTask* task = compile_queue->first(); task != NULL;) {
+ CompileTask* next_task = task->next();
+ Method* method = task->method();
+ // If a method was unloaded or has been stale for some time, remove it from the queue.
+ // Blocking tasks and tasks submitted from whitebox API don't become stale
+ if (task->is_unloaded() || (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method))) {
+ if (!task->is_unloaded()) {
+ if (PrintTieredEvents) {
+ print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel) task->comp_level());
+ }
+ method->clear_queued_for_compilation();
+ }
+ compile_queue->remove_and_mark_stale(task);
+ task = next_task;
+ continue;
+ }
+ update_rate(t, method);
+ if (max_task == NULL || compare_methods(method, max_method)) {
+ // Select a method with the highest rate
+ max_task = task;
+ max_method = method;
+ }
+
+ if (task->is_blocking()) {
+ if (max_blocking_task == NULL || compare_methods(method, max_blocking_task->method())) {
+ max_blocking_task = task;
+ }
+ }
+
+ task = next_task;
+ }
+
+ if (max_blocking_task != NULL) {
+ // In blocking compilation mode, the CompileBroker will make
+ // compilations submitted by a JVMCI compiler thread non-blocking. These
+ // compilations should be scheduled after all blocking compilations
+ // to service non-compiler related compilations sooner and reduce the
+ // chance of such compilations timing out.
+ max_task = max_blocking_task;
+ max_method = max_task->method();
+ }
+
+ if (max_task != NULL && max_task->comp_level() == CompLevel_full_profile &&
+ TieredStopAtLevel > CompLevel_full_profile &&
+ max_method != NULL && is_method_profiled(max_method)) {
+ max_task->set_comp_level(CompLevel_limited_profile);
+
+ if (CompileBroker::compilation_is_complete(max_method, max_task->osr_bci(), CompLevel_limited_profile)) {
+ if (PrintTieredEvents) {
+ print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
+ }
+ compile_queue->remove_and_mark_stale(max_task);
+ max_method->clear_queued_for_compilation();
+ return NULL;
+ }
+
+ if (PrintTieredEvents) {
+ print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
+ }
+ }
+
+ return max_task;
+}
+
+void TieredThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
+ for (ScopeDesc* sd = trap_scope;; sd = sd->sender()) {
+ if (PrintTieredEvents) {
+ methodHandle mh(sd->method());
+ print_event(REPROFILE, mh, mh, InvocationEntryBci, CompLevel_none);
+ }
+ MethodData* mdo = sd->method()->method_data();
+ if (mdo != NULL) {
+ mdo->reset_start_counters();
+ }
+ if (sd->is_top()) break;
+ }
+}
+
+nmethod* TieredThresholdPolicy::event(const methodHandle& method, const methodHandle& inlinee,
+ int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
+ if (comp_level == CompLevel_none &&
+ JvmtiExport::can_post_interpreter_events() &&
+ thread->is_interp_only_mode()) {
+ return NULL;
+ }
+ if (ReplayCompiles) {
+ // Don't trigger other compiles in testing mode
+ return NULL;
+ }
+
+ handle_counter_overflow(method());
+ if (method() != inlinee()) {
+ handle_counter_overflow(inlinee());
+ }
+
+ if (PrintTieredEvents) {
+ print_event(bci == InvocationEntryBci ? CALL : LOOP, method, inlinee, bci, comp_level);
+ }
+
+ if (bci == InvocationEntryBci) {
+ method_invocation_event(method, inlinee, comp_level, nm, thread);
+ } else {
+ // method == inlinee if the event originated in the main method
+ method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
+ // Check if event led to a higher level OSR compilation
+ CompLevel expected_comp_level = comp_level;
+ if (inlinee->is_not_osr_compilable(expected_comp_level)) {
+ // It's not possble to reach the expected level so fall back to simple.
+ expected_comp_level = CompLevel_simple;
+ }
+ nmethod* osr_nm = inlinee->lookup_osr_nmethod_for(bci, expected_comp_level, false);
+ assert(osr_nm == NULL || osr_nm->comp_level() >= expected_comp_level, "lookup_osr_nmethod_for is broken");
+ if (osr_nm != NULL) {
+ // Perform OSR with new nmethod
+ return osr_nm;
+ }
+ }
+ return NULL;
+}
+
+// Check if the method can be compiled, change level if necessary
+void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
+ assert(level <= TieredStopAtLevel, "Invalid compilation level");
+ if (level == CompLevel_none) {
+ return;
+ }
+ if (level == CompLevel_aot) {
+ if (mh->has_aot_code()) {
+ if (PrintTieredEvents) {
+ print_event(COMPILE, mh, mh, bci, level);
+ }
+ MutexLocker ml(Compile_lock);
+ NoSafepointVerifier nsv;
+ if (mh->has_aot_code() && mh->code() != mh->aot_code()) {
+ mh->aot_code()->make_entrant();
+ if (mh->has_compiled_code()) {
+ mh->code()->make_not_entrant();
+ }
+ MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+ Method::set_code(mh, mh->aot_code());
+ }
+ }
+ return;
+ }
+
+ // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling
+ // in the interpreter and then compile with C2 (the transition function will request that,
+ // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with
+ // pure C1.
+ if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) {
+ if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) {
+ compile(mh, bci, CompLevel_simple, thread);
+ }
+ return;
+ }
+ if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) {
+ if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) {
+ nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false);
+ if (osr_nm != NULL && osr_nm->comp_level() > CompLevel_simple) {
+ // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted.
+ osr_nm->make_not_entrant();
+ }
+ compile(mh, bci, CompLevel_simple, thread);
+ }
+ return;
+ }
+ if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) {
+ return;
+ }
+ if (!CompileBroker::compilation_is_in_queue(mh)) {
+ if (PrintTieredEvents) {
+ print_event(COMPILE, mh, mh, bci, level);
+ }
+ submit_compile(mh, bci, level, thread);
+ }
+}
+
+// Update the rate and submit compile
+void TieredThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
+ int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
+ update_rate(os::javaTimeMillis(), mh());
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
+}
+
+// Print an event.
+void TieredThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh,
+ int bci, CompLevel level) {
+ tty->print(" rate=");
+ if (mh->prev_time() == 0) tty->print("n/a");
+ else tty->print("%f", mh->rate());
+
+ tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
+ threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
+
+}
+
+// update_rate() is called from select_task() while holding a compile queue lock.
+void TieredThresholdPolicy::update_rate(jlong t, Method* m) {
+ // Skip update if counters are absent.
+ // Can't allocate them since we are holding compile queue lock.
+ if (m->method_counters() == NULL) return;
+
+ if (is_old(m)) {
+ // We don't remove old methods from the queue,
+ // so we can just zero the rate.
+ m->set_rate(0);
+ return;
+ }
+
+ // We don't update the rate if we've just came out of a safepoint.
+ // delta_s is the time since last safepoint in milliseconds.
+ jlong delta_s = t - SafepointTracing::end_of_last_safepoint_epoch_ms();
+ jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement
+ // How many events were there since the last time?
+ int event_count = m->invocation_count() + m->backedge_count();
+ int delta_e = event_count - m->prev_event_count();
+
+ // We should be running for at least 1ms.
+ if (delta_s >= TieredRateUpdateMinTime) {
+ // And we must've taken the previous point at least 1ms before.
+ if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
+ m->set_prev_time(t);
+ m->set_prev_event_count(event_count);
+ m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
+ } else {
+ if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
+ // If nothing happened for 25ms, zero the rate. Don't modify prev values.
+ m->set_rate(0);
+ }
+ }
+ }
+}
+
+// Check if this method has been stale for a given number of milliseconds.
+// See select_task().
+bool TieredThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) {
+ jlong delta_s = t - SafepointTracing::end_of_last_safepoint_epoch_ms();
+ jlong delta_t = t - m->prev_time();
+ if (delta_t > timeout && delta_s > timeout) {
+ int event_count = m->invocation_count() + m->backedge_count();
+ int delta_e = event_count - m->prev_event_count();
+ // Return true if there were no events.
+ return delta_e == 0;
+ }
+ return false;
+}
+
+// We don't remove old methods from the compile queue even if they have
+// very low activity. See select_task().
+bool TieredThresholdPolicy::is_old(Method* method) {
+ return method->invocation_count() > 50000 || method->backedge_count() > 500000;
+}
+
+double TieredThresholdPolicy::weight(Method* method) {
+ return (double)(method->rate() + 1) *
+ (method->invocation_count() + 1) * (method->backedge_count() + 1);
+}
+
+// Apply heuristics and return true if x should be compiled before y
+bool TieredThresholdPolicy::compare_methods(Method* x, Method* y) {
+ if (x->highest_comp_level() > y->highest_comp_level()) {
+ // recompilation after deopt
+ return true;
+ } else
+ if (x->highest_comp_level() == y->highest_comp_level()) {
+ if (weight(x) > weight(y)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Is method profiled enough?
+bool TieredThresholdPolicy::is_method_profiled(Method* method) {
+ MethodData* mdo = method->method_data();
+ if (mdo != NULL) {
+ int i = mdo->invocation_count_delta();
+ int b = mdo->backedge_count_delta();
+ return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
+ }
+ return false;
+}
+
+double TieredThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
+ double queue_size = CompileBroker::queue_size(level);
+ int comp_count = compiler_count(level);
+ double k = queue_size / (feedback_k * comp_count) + 1;
+
+ // Increase C1 compile threshold when the code cache is filled more
+ // than specified by IncreaseFirstTierCompileThresholdAt percentage.
+ // The main intention is to keep enough free space for C2 compiled code
+ // to achieve peak performance if the code cache is under stress.
+ if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization)) {
+ double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level));
+ if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
+ k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
+ }
+ }
+ return k;
+}
+
+// Call and loop predicates determine whether a transition to a higher
+// compilation level should be performed (pointers to predicate functions
+// are passed to common()).
+// Tier?LoadFeedback is basically a coefficient that determines of
+// how many methods per compiler thread can be in the queue before
+// the threshold values double.
+bool TieredThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
+ switch(cur_level) {
+ case CompLevel_aot: {
+ double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+ return loop_predicate_helper<CompLevel_aot>(i, b, k, method);
+ }
+ case CompLevel_none:
+ case CompLevel_limited_profile: {
+ double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+ return loop_predicate_helper<CompLevel_none>(i, b, k, method);
+ }
+ case CompLevel_full_profile: {
+ double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
+ return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
+ }
+ default:
+ return true;
+ }
+}
+
+bool TieredThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
+ switch(cur_level) {
+ case CompLevel_aot: {
+ double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+ return call_predicate_helper<CompLevel_aot>(i, b, k, method);
+ }
+ case CompLevel_none:
+ case CompLevel_limited_profile: {
+ double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+ return call_predicate_helper<CompLevel_none>(i, b, k, method);
+ }
+ case CompLevel_full_profile: {
+ double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
+ return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
+ }
+ default:
+ return true;
+ }
+}
+
+// Determine is a method is mature.
+bool TieredThresholdPolicy::is_mature(Method* method) {
+ if (should_compile_at_level_simple(method)) return true;
+ MethodData* mdo = method->method_data();
+ if (mdo != NULL) {
+ int i = mdo->invocation_count();
+ int b = mdo->backedge_count();
+ double k = ProfileMaturityPercentage / 100.0;
+ return call_predicate_helper<CompLevel_full_profile>(i, b, k, method) ||
+ loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
+ }
+ return false;
+}
+
+// If a method is old enough and is still in the interpreter we would want to
+// start profiling without waiting for the compiled method to arrive.
+// We also take the load on compilers into the account.
+bool TieredThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) {
+ if (cur_level == CompLevel_none &&
+ CompileBroker::queue_size(CompLevel_full_optimization) <=
+ Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+ int i = method->invocation_count();
+ int b = method->backedge_count();
+ double k = Tier0ProfilingStartPercentage / 100.0;
+ return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
+ }
+ return false;
+}
+
+// Inlining control: if we're compiling a profiled method with C1 and the callee
+// is known to have OSRed in a C2 version, don't inline it.
+bool TieredThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) {
+ CompLevel comp_level = (CompLevel)env->comp_level();
+ if (comp_level == CompLevel_full_profile ||
+ comp_level == CompLevel_limited_profile) {
+ return callee->highest_osr_comp_level() == CompLevel_full_optimization;
+ }
+ return false;
+}
+
+// Create MDO if necessary.
+void TieredThresholdPolicy::create_mdo(const methodHandle& mh, JavaThread* THREAD) {
+ if (mh->is_native() ||
+ mh->is_abstract() ||
+ mh->is_accessor() ||
+ mh->is_constant_getter()) {
+ return;
+ }
+ if (mh->method_data() == NULL) {
+ Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
+ }
+}
+
+
+/*
+ * Method states:
+ * 0 - interpreter (CompLevel_none)
+ * 1 - pure C1 (CompLevel_simple)
+ * 2 - C1 with invocation and backedge counting (CompLevel_limited_profile)
+ * 3 - C1 with full profiling (CompLevel_full_profile)
+ * 4 - C2 (CompLevel_full_optimization)
+ *
+ * Common state transition patterns:
+ * a. 0 -> 3 -> 4.
+ * The most common path. But note that even in this straightforward case
+ * profiling can start at level 0 and finish at level 3.
+ *
+ * b. 0 -> 2 -> 3 -> 4.
+ * This case occurs when the load on C2 is deemed too high. So, instead of transitioning
+ * into state 3 directly and over-profiling while a method is in the C2 queue we transition to
+ * level 2 and wait until the load on C2 decreases. This path is disabled for OSRs.
+ *
+ * c. 0 -> (3->2) -> 4.
+ * In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
+ * to enable the profiling to fully occur at level 0. In this case we change the compilation level
+ * of the method to 2 while the request is still in-queue, because it'll allow it to run much faster
+ * without full profiling while c2 is compiling.
+ *
+ * d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
+ * After a method was once compiled with C1 it can be identified as trivial and be compiled to
+ * level 1. These transition can also occur if a method can't be compiled with C2 but can with C1.
+ *
+ * e. 0 -> 4.
+ * This can happen if a method fails C1 compilation (it will still be profiled in the interpreter)
+ * or because of a deopt that didn't require reprofiling (compilation won't happen in this case because
+ * the compiled version already exists).
+ *
+ * Note that since state 0 can be reached from any other state via deoptimization different loops
+ * are possible.
+ *
+ */
+
+// Common transition function. Given a predicate determines if a method should transition to another level.
+CompLevel TieredThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback) {
+ CompLevel next_level = cur_level;
+ int i = method->invocation_count();
+ int b = method->backedge_count();
+
+ if (should_compile_at_level_simple(method)) {
+ next_level = CompLevel_simple;
+ } else {
+ switch(cur_level) {
+ default: break;
+ case CompLevel_aot: {
+ // If we were at full profile level, would we switch to full opt?
+ if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
+ next_level = CompLevel_full_optimization;
+ } else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
+ Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+ (this->*p)(i, b, cur_level, method))) {
+ next_level = CompLevel_full_profile;
+ }
+ }
+ break;
+ case CompLevel_none:
+ // If we were at full profile level, would we switch to full opt?
+ if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
+ next_level = CompLevel_full_optimization;
+ } else if ((this->*p)(i, b, cur_level, method)) {
+#if INCLUDE_JVMCI
+ if (EnableJVMCI && UseJVMCICompiler) {
+ // Since JVMCI takes a while to warm up, its queue inevitably backs up during
+ // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root
+ // compilation method and all potential inlinees have mature profiles (which
+ // includes type profiling). If it sees immature profiles, JVMCI's inliner
+ // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to
+ // exploring/inlining too many graphs). Since a rewrite of the inliner is
+ // in progress, we simply disable the dialing back heuristic for now and will
+ // revisit this decision once the new inliner is completed.
+ next_level = CompLevel_full_profile;
+ } else
+#endif
+ {
+ // C1-generated fully profiled code is about 30% slower than the limited profile
+ // code that has only invocation and backedge counters. The observation is that
+ // if C2 queue is large enough we can spend too much time in the fully profiled code
+ // while waiting for C2 to pick the method from the queue. To alleviate this problem
+ // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
+ // we choose to compile a limited profiled version and then recompile with full profiling
+ // when the load on C2 goes down.
+ if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
+ Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+ next_level = CompLevel_limited_profile;
+ } else {
+ next_level = CompLevel_full_profile;
+ }
+ }
+ }
+ break;
+ case CompLevel_limited_profile:
+ if (is_method_profiled(method)) {
+ // Special case: we got here because this method was fully profiled in the interpreter.
+ next_level = CompLevel_full_optimization;
+ } else {
+ MethodData* mdo = method->method_data();
+ if (mdo != NULL) {
+ if (mdo->would_profile()) {
+ if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
+ Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+ (this->*p)(i, b, cur_level, method))) {
+ next_level = CompLevel_full_profile;
+ }
+ } else {
+ next_level = CompLevel_full_optimization;
+ }
+ } else {
+ // If there is no MDO we need to profile
+ if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
+ Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+ (this->*p)(i, b, cur_level, method))) {
+ next_level = CompLevel_full_profile;
+ }
+ }
+ }
+ break;
+ case CompLevel_full_profile:
+ {
+ MethodData* mdo = method->method_data();
+ if (mdo != NULL) {
+ if (mdo->would_profile()) {
+ int mdo_i = mdo->invocation_count_delta();
+ int mdo_b = mdo->backedge_count_delta();
+ if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
+ next_level = CompLevel_full_optimization;
+ }
+ } else {
+ next_level = CompLevel_full_optimization;
+ }
+ }
+ }
+ break;
+ }
+ }
+ return MIN2(next_level, (CompLevel)TieredStopAtLevel);
+}
+
+// Determine if a method should be compiled with a normal entry point at a different level.
+CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) {
+ CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
+ common(&TieredThresholdPolicy::loop_predicate, method, cur_level, true));
+ CompLevel next_level = common(&TieredThresholdPolicy::call_predicate, method, cur_level);
+
+ // If OSR method level is greater than the regular method level, the levels should be
+ // equalized by raising the regular method level in order to avoid OSRs during each
+ // invocation of the method.
+ if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) {
+ MethodData* mdo = method->method_data();
+ guarantee(mdo != NULL, "MDO should not be NULL");
+ if (mdo->invocation_count() >= 1) {
+ next_level = CompLevel_full_optimization;
+ }
+ } else {
+ next_level = MAX2(osr_level, next_level);
+ }
+ return next_level;
+}
+
+// Determine if we should do an OSR compilation of a given method.
+CompLevel TieredThresholdPolicy::loop_event(Method* method, CompLevel cur_level, JavaThread* thread) {
+ CompLevel next_level = common(&TieredThresholdPolicy::loop_predicate, method, cur_level, true);
+ if (cur_level == CompLevel_none) {
+ // If there is a live OSR method that means that we deopted to the interpreter
+ // for the transition.
+ CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level);
+ if (osr_level > CompLevel_none) {
+ return osr_level;
+ }
+ }
+ return next_level;
+}
+
+bool TieredThresholdPolicy::maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread) {
+ if (UseAOT) {
+ if (cur_level == CompLevel_full_profile || cur_level == CompLevel_none) {
+ // If the current level is full profile or interpreter and we're switching to any other level,
+ // activate the AOT code back first so that we won't waste time overprofiling.
+ compile(mh, InvocationEntryBci, CompLevel_aot, thread);
+ // Fall through for JIT compilation.
+ }
+ if (next_level == CompLevel_limited_profile && cur_level != CompLevel_aot && mh->has_aot_code()) {
+ // If the next level is limited profile, use the aot code (if there is any),
+ // since it's essentially the same thing.
+ compile(mh, InvocationEntryBci, CompLevel_aot, thread);
+ // Not need to JIT, we're done.
+ return true;
+ }
+ }
+ return false;
+}
+
+
+// Handle the invocation event.
+void TieredThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
+ CompLevel level, CompiledMethod* nm, JavaThread* thread) {
+ if (should_create_mdo(mh(), level)) {
+ create_mdo(mh, thread);
+ }
+ CompLevel next_level = call_event(mh(), level, thread);
+ if (next_level != level) {
+ if (maybe_switch_to_aot(mh, level, next_level, thread)) {
+ // No JITting necessary
+ return;
+ }
+ if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
+ compile(mh, InvocationEntryBci, next_level, thread);
+ }
+ }
+}
+
+// Handle the back branch event. Notice that we can compile the method
+// with a regular entry from here.
+void TieredThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
+ int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
+ if (should_create_mdo(mh(), level)) {
+ create_mdo(mh, thread);
+ }
+ // Check if MDO should be created for the inlined method
+ if (should_create_mdo(imh(), level)) {
+ create_mdo(imh, thread);
+ }
+
+ if (is_compilation_enabled()) {
+ CompLevel next_osr_level = loop_event(imh(), level, thread);
+ CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
+ // At the very least compile the OSR version
+ if (!CompileBroker::compilation_is_in_queue(imh) && (next_osr_level != level)) {
+ compile(imh, bci, next_osr_level, thread);
+ }
+
+ // Use loop event as an opportunity to also check if there's been
+ // enough calls.
+ CompLevel cur_level, next_level;
+ if (mh() != imh()) { // If there is an enclosing method
+ if (level == CompLevel_aot) {
+ // Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
+ if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
+ compile(mh, InvocationEntryBci, MIN2((CompLevel)TieredStopAtLevel, CompLevel_full_profile), thread);
+ }
+ } else {
+ // Current loop event level is not AOT
+ guarantee(nm != NULL, "Should have nmethod here");
+ cur_level = comp_level(mh());
+ next_level = call_event(mh(), cur_level, thread);
+
+ if (max_osr_level == CompLevel_full_optimization) {
+ // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts
+ bool make_not_entrant = false;
+ if (nm->is_osr_method()) {
+ // This is an osr method, just make it not entrant and recompile later if needed
+ make_not_entrant = true;
+ } else {
+ if (next_level != CompLevel_full_optimization) {
+ // next_level is not full opt, so we need to recompile the
+ // enclosing method without the inlinee
+ cur_level = CompLevel_none;
+ make_not_entrant = true;
+ }
+ }
+ if (make_not_entrant) {
+ if (PrintTieredEvents) {
+ int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci;
+ print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level);
+ }
+ nm->make_not_entrant();
+ }
+ }
+ // Fix up next_level if necessary to avoid deopts
+ if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) {
+ next_level = CompLevel_full_profile;
+ }
+ if (cur_level != next_level) {
+ if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
+ compile(mh, InvocationEntryBci, next_level, thread);
+ }
+ }
+ }
+ } else {
+ cur_level = comp_level(mh());
+ next_level = call_event(mh(), cur_level, thread);
+ if (next_level != cur_level) {
+ if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
+ compile(mh, InvocationEntryBci, next_level, thread);
+ }
+ }
+ }
+ }
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/tieredThresholdPolicy.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,278 @@
+/*
+ * 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
+ * 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_COMPILER_TIEREDTHRESHOLDPOLICY_HPP
+#define SHARE_COMPILER_TIEREDTHRESHOLDPOLICY_HPP
+
+#include "code/nmethod.hpp"
+#include "compiler/compilationPolicy.hpp"
+#include "oops/methodData.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#ifdef TIERED
+
+class CompileTask;
+class CompileQueue;
+/*
+ * The system supports 5 execution levels:
+ * * level 0 - interpreter
+ * * level 1 - C1 with full optimization (no profiling)
+ * * level 2 - C1 with invocation and backedge counters
+ * * level 3 - C1 with full profiling (level 2 + MDO)
+ * * level 4 - C2
+ *
+ * Levels 0, 2 and 3 periodically notify the runtime about the current value of the counters
+ * (invocation counters and backedge counters). The frequency of these notifications is
+ * different at each level. These notifications are used by the policy to decide what transition
+ * to make.
+ *
+ * Execution starts at level 0 (interpreter), then the policy can decide either to compile the
+ * method at level 3 or level 2. The decision is based on the following factors:
+ * 1. The length of the C2 queue determines the next level. The observation is that level 2
+ * is generally faster than level 3 by about 30%, therefore we would want to minimize the time
+ * a method spends at level 3. We should only spend the time at level 3 that is necessary to get
+ * adequate profiling. So, if the C2 queue is long enough it is more beneficial to go first to
+ * level 2, because if we transitioned to level 3 we would be stuck there until our C2 compile
+ * request makes its way through the long queue. When the load on C2 recedes we are going to
+ * recompile at level 3 and start gathering profiling information.
+ * 2. The length of C1 queue is used to dynamically adjust the thresholds, so as to introduce
+ * additional filtering if the compiler is overloaded. The rationale is that by the time a
+ * method gets compiled it can become unused, so it doesn't make sense to put too much onto the
+ * queue.
+ *
+ * After profiling is completed at level 3 the transition is made to level 4. Again, the length
+ * of the C2 queue is used as a feedback to adjust the thresholds.
+ *
+ * After the first C1 compile some basic information is determined about the code like the number
+ * of the blocks and the number of the loops. Based on that it can be decided that a method
+ * is trivial and compiling it with C1 will yield the same code. In this case the method is
+ * compiled at level 1 instead of 4.
+ *
+ * We also support profiling at level 0. If C1 is slow enough to produce the level 3 version of
+ * the code and the C2 queue is sufficiently small we can decide to start profiling in the
+ * interpreter (and continue profiling in the compiled code once the level 3 version arrives).
+ * If the profiling at level 0 is fully completed before level 3 version is produced, a level 2
+ * version is compiled instead in order to run faster waiting for a level 4 version.
+ *
+ * Compile queues are implemented as priority queues - for each method in the queue we compute
+ * the event rate (the number of invocation and backedge counter increments per unit of time).
+ * When getting an element off the queue we pick the one with the largest rate. Maintaining the
+ * rate also allows us to remove stale methods (the ones that got on the queue but stopped
+ * being used shortly after that).
+*/
+
+/* Command line options:
+ * - Tier?InvokeNotifyFreqLog and Tier?BackedgeNotifyFreqLog control the frequency of method
+ * invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
+ * makes a call into the runtime.
+ *
+ * - Tier?InvocationThreshold, Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
+ * compilation thresholds.
+ * Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
+ * Other thresholds work as follows:
+ *
+ * Transition from interpreter (level 0) to C1 with full profiling (level 3) happens when
+ * the following predicate is true (X is the level):
+ *
+ * i > TierXInvocationThreshold * s || (i > TierXMinInvocationThreshold * s && i + b > TierXCompileThreshold * s),
+ *
+ * where $i$ is the number of method invocations, $b$ number of backedges and $s$ is the scaling
+ * coefficient that will be discussed further.
+ * The intuition is to equalize the time that is spend profiling each method.
+ * The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
+ * noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
+ * from Method* and for 3->4 transition they come from MDO (since profiled invocations are
+ * counted separately). Finally, if a method does not contain anything worth profiling, a transition
+ * from level 3 to level 4 occurs without considering thresholds (e.g., with fewer invocations than
+ * what is specified by Tier4InvocationThreshold).
+ *
+ * OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
+ *
+ * - Tier?LoadFeedback options are used to automatically scale the predicates described above depending
+ * on the compiler load. The scaling coefficients are computed as follows:
+ *
+ * s = queue_size_X / (TierXLoadFeedback * compiler_count_X) + 1,
+ *
+ * where queue_size_X is the current size of the compiler queue of level X, and compiler_count_X
+ * is the number of level X compiler threads.
+ *
+ * Basically these parameters describe how many methods should be in the compile queue
+ * per compiler thread before the scaling coefficient increases by one.
+ *
+ * This feedback provides the mechanism to automatically control the flow of compilation requests
+ * depending on the machine speed, mutator load and other external factors.
+ *
+ * - Tier3DelayOn and Tier3DelayOff parameters control another important feedback loop.
+ * Consider the following observation: a method compiled with full profiling (level 3)
+ * is about 30% slower than a method at level 2 (just invocation and backedge counters, no MDO).
+ * Normally, the following transitions will occur: 0->3->4. The problem arises when the C2 queue
+ * gets congested and the 3->4 transition is delayed. While the method is the C2 queue it continues
+ * executing at level 3 for much longer time than is required by the predicate and at suboptimal speed.
+ * The idea is to dynamically change the behavior of the system in such a way that if a substantial
+ * load on C2 is detected we would first do the 0->2 transition allowing a method to run faster.
+ * And then when the load decreases to allow 2->3 transitions.
+ *
+ * Tier3Delay* parameters control this switching mechanism.
+ * Tier3DelayOn is the number of methods in the C2 queue per compiler thread after which the policy
+ * no longer does 0->3 transitions but does 0->2 transitions instead.
+ * Tier3DelayOff switches the original behavior back when the number of methods in the C2 queue
+ * per compiler thread falls below the specified amount.
+ * The hysteresis is necessary to avoid jitter.
+ *
+ * - TieredCompileTaskTimeout is the amount of time an idle method can spend in the compile queue.
+ * Basically, since we use the event rate d(i + b)/dt as a value of priority when selecting a method to
+ * compile from the compile queue, we also can detect stale methods for which the rate has been
+ * 0 for some time in the same iteration. Stale methods can appear in the queue when an application
+ * abruptly changes its behavior.
+ *
+ * - TieredStopAtLevel, is used mostly for testing. It allows to bypass the policy logic and stick
+ * to a given level. For example it's useful to set TieredStopAtLevel = 1 in order to compile everything
+ * with pure c1.
+ *
+ * - Tier0ProfilingStartPercentage allows the interpreter to start profiling when the inequalities in the
+ * 0->3 predicate are already exceeded by the given percentage but the level 3 version of the
+ * method is still not ready. We can even go directly from level 0 to 4 if c1 doesn't produce a compiled
+ * version in time. This reduces the overall transition to level 4 and decreases the startup time.
+ * Note that this behavior is also guarded by the Tier3Delay mechanism: when the c2 queue is too long
+ * these is not reason to start profiling prematurely.
+ *
+ * - TieredRateUpdateMinTime and TieredRateUpdateMaxTime are parameters of the rate computation.
+ * Basically, the rate is not computed more frequently than TieredRateUpdateMinTime and is considered
+ * to be zero if no events occurred in TieredRateUpdateMaxTime.
+ */
+
+class TieredThresholdPolicy : public CompilationPolicy {
+ jlong _start_time;
+ int _c1_count, _c2_count;
+
+ // Check if the counter is big enough and set carry (effectively infinity).
+ inline void set_carry_if_necessary(InvocationCounter *counter);
+ // Set carry flags in the counters (in Method* and MDO).
+ inline void handle_counter_overflow(Method* method);
+ // Call and loop predicates determine whether a transition to a higher compilation
+ // level should be performed (pointers to predicate functions are passed to common_TF().
+ // Predicates also take compiler load into account.
+ typedef bool (TieredThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
+ bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
+ bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
+ // Common transition function. Given a predicate determines if a method should transition to another level.
+ CompLevel common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback = false);
+ // Transition functions.
+ // call_event determines if a method should be compiled at a different
+ // level with a regular invocation entry.
+ CompLevel call_event(Method* method, CompLevel cur_level, JavaThread* thread);
+ // loop_event checks if a method should be OSR compiled at a different
+ // level.
+ CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread* thread);
+ void print_counters(const char* prefix, const methodHandle& mh);
+ // Has a method been long around?
+ // We don't remove old methods from the compile queue even if they have
+ // very low activity (see select_task()).
+ inline bool is_old(Method* method);
+ // Was a given method inactive for a given number of milliseconds.
+ // If it is, we would remove it from the queue (see select_task()).
+ inline bool is_stale(jlong t, jlong timeout, Method* m);
+ // Compute the weight of the method for the compilation scheduling
+ inline double weight(Method* method);
+ // Apply heuristics and return true if x should be compiled before y
+ inline bool compare_methods(Method* x, Method* y);
+ // Compute event rate for a given method. The rate is the number of event (invocations + backedges)
+ // per millisecond.
+ inline void update_rate(jlong t, Method* m);
+ // Compute threshold scaling coefficient
+ inline double threshold_scale(CompLevel level, int feedback_k);
+ // If a method is old enough and is still in the interpreter we would want to
+ // start profiling without waiting for the compiled method to arrive. This function
+ // determines whether we should do that.
+ inline bool should_create_mdo(Method* method, CompLevel cur_level);
+ // Create MDO if necessary.
+ void create_mdo(const methodHandle& mh, JavaThread* thread);
+ // Is method profiled enough?
+ bool is_method_profiled(Method* method);
+
+ double _increase_threshold_at_ratio;
+
+ bool maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread);
+
+ int c1_count() const { return _c1_count; }
+ int c2_count() const { return _c2_count; }
+ void set_c1_count(int x) { _c1_count = x; }
+ void set_c2_count(int x) { _c2_count = x; }
+
+ enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
+ void print_event(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
+ // Print policy-specific information if necessary
+ void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
+ // Check if the method can be compiled, change level if necessary
+ void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
+ // Submit a given method for compilation
+ void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
+ // Simple methods are as good being compiled with C1 as C2.
+ // This function tells if it's such a function.
+ inline static bool is_trivial(Method* method);
+ // Force method to be compiled at CompLevel_simple?
+ inline static bool should_compile_at_level_simple(Method* method);
+
+ // Predicate helpers are used by .*_predicate() methods as well as others.
+ // They check the given counter values, multiplied by the scale against the thresholds.
+ template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale, Method* method);
+ template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale, Method* method);
+
+ // Get a compilation level for a given method.
+ static CompLevel comp_level(Method* method);
+ void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
+ CompLevel level, CompiledMethod* nm, JavaThread* thread);
+ void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
+ int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread);
+
+ void set_increase_threshold_at_ratio() { _increase_threshold_at_ratio = 100 / (100 - (double)IncreaseFirstTierCompileThresholdAt); }
+ void set_start_time(jlong t) { _start_time = t; }
+ jlong start_time() const { return _start_time; }
+
+public:
+ TieredThresholdPolicy() : _start_time(0), _c1_count(0), _c2_count(0) { }
+ virtual int compiler_count(CompLevel comp_level) {
+ if (is_c1_compile(comp_level)) return c1_count();
+ if (is_c2_compile(comp_level)) return c2_count();
+ return 0;
+ }
+ virtual CompLevel initial_compile_level() { return MIN2((CompLevel)TieredStopAtLevel, CompLevel_initial_compile); }
+ virtual void do_safepoint_work() { }
+ virtual void delay_compilation(Method* method) { }
+ virtual void disable_compilation(Method* method) { }
+ virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
+ virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee,
+ int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
+ // Select task is called by CompileBroker. We should return a task or NULL.
+ virtual CompileTask* select_task(CompileQueue* compile_queue);
+ // Tell the runtime if we think a given method is adequately profiled.
+ virtual bool is_mature(Method* method);
+ // Initialize: set compiler thread count
+ virtual void initialize();
+ virtual bool should_not_inline(ciEnv* env, ciMethod* callee);
+};
+
+#endif // TIERED
+
+#endif // SHARE_COMPILER_TIEREDTHRESHOLDPOLICY_HPP
--- a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -45,13 +45,25 @@
FLAG_SET_DEFAULT(ExitOnOutOfMemoryError, true);
}
+ // Warn users that non-resizable heap might be better for some configurations.
+ // We are not adjusting the heap size by ourselves, because it affects startup time.
+ if (InitialHeapSize != MaxHeapSize) {
+ log_warning(gc)("Consider setting -Xms equal to -Xmx to avoid resizing hiccups");
+ }
+
+ // Warn users that AlwaysPreTouch might be better for some configurations.
+ // We are not turning this on by ourselves, because it affects startup time.
+ if (FLAG_IS_DEFAULT(AlwaysPreTouch) && !AlwaysPreTouch) {
+ log_warning(gc)("Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups");
+ }
+
if (EpsilonMaxTLABSize < MinTLABSize) {
- warning("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
+ log_warning(gc)("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
EpsilonMaxTLABSize = MinTLABSize;
}
if (!EpsilonElasticTLAB && EpsilonElasticTLABDecay) {
- warning("Disabling EpsilonElasticTLABDecay because EpsilonElasticTLAB is disabled");
+ log_warning(gc)("Disabling EpsilonElasticTLABDecay because EpsilonElasticTLAB is disabled");
FLAG_SET_DEFAULT(EpsilonElasticTLABDecay, false);
}
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -186,10 +186,6 @@
_collision_list_next(NULL)
{}
- inline void add_card_work(CardIdx_t from_card, bool par);
-
- inline void add_reference_work(OopOrNarrowOopStar from, bool par);
-
public:
// We need access in order to union things into the base table.
BitMap* bm() { return &_bm; }
@@ -206,12 +202,8 @@
inline void add_reference(OopOrNarrowOopStar from);
- inline void seq_add_reference(OopOrNarrowOopStar from);
-
inline void add_card(CardIdx_t from_card_index);
- void seq_add_card(CardIdx_t from_card_index);
-
// (Destructively) union the bitmap of the current table into the given
// bitmap (which is assumed to be of the same size.)
void union_bitmap_into(BitMap* bm) {
@@ -381,12 +373,6 @@
_state = Complete;
}
- // Used in the sequential case.
- void add_reference(OopOrNarrowOopStar from) {
- add_reference(from, 0);
- }
-
- // Used in the parallel case.
void add_reference(OopOrNarrowOopStar from, uint tid) {
RemSetState state = _state;
if (state == Untracked) {
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -35,20 +35,13 @@
_other_regions.iterate(cl);
}
-inline void PerRegionTable::add_card_work(CardIdx_t from_card, bool par) {
- if (!_bm.at(from_card)) {
- if (par) {
- if (_bm.par_set_bit(from_card)) {
- Atomic::inc(&_occupied);
- }
- } else {
- _bm.set_bit(from_card);
- _occupied++;
- }
+inline void PerRegionTable::add_card(CardIdx_t from_card_index) {
+ if (_bm.par_set_bit(from_card_index)) {
+ Atomic::inc(&_occupied);
}
}
-inline void PerRegionTable::add_reference_work(OopOrNarrowOopStar from, bool par) {
+inline void PerRegionTable::add_reference(OopOrNarrowOopStar from) {
// Must make this robust in case "from" is not in "_hr", because of
// concurrency.
@@ -58,26 +51,10 @@
// and adding a bit to the new table is never incorrect.
if (loc_hr->is_in_reserved(from)) {
CardIdx_t from_card = OtherRegionsTable::card_within_region(from, loc_hr);
- add_card_work(from_card, par);
+ add_card(from_card);
}
}
-inline void PerRegionTable::add_card(CardIdx_t from_card_index) {
- add_card_work(from_card_index, /*parallel*/ true);
-}
-
-inline void PerRegionTable::seq_add_card(CardIdx_t from_card_index) {
- add_card_work(from_card_index, /*parallel*/ false);
-}
-
-inline void PerRegionTable::add_reference(OopOrNarrowOopStar from) {
- add_reference_work(from, /*parallel*/ true);
-}
-
-inline void PerRegionTable::seq_add_reference(OopOrNarrowOopStar from) {
- add_reference_work(from, /*parallel*/ false);
-}
-
inline void PerRegionTable::init(HeapRegion* hr, bool clear_links_to_all_list) {
if (clear_links_to_all_list) {
set_next(NULL);
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -66,9 +66,12 @@
size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0;
size_t max_cset = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste);
- log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "M, Actual Free: "
- SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M, Min Garbage: " SIZE_FORMAT "M",
- free_target / M, actual_free / M, max_cset / M, min_garbage / M);
+ log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "%s, Actual Free: "
+ SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s, Min Garbage: " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(free_target), proper_unit_for_byte_size(free_target),
+ byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free),
+ byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset),
+ byte_size_in_proper_unit(min_garbage), proper_unit_for_byte_size(min_garbage));
// Better select garbage-first regions
QuickSort::sort<RegionData>(data, (int)size, compare_by_garbage, false);
@@ -119,8 +122,9 @@
// anything else.
size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
if (available < min_threshold) {
- log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
- available / M, min_threshold / M);
+ log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold));
return true;
}
@@ -129,8 +133,10 @@
if (_gc_times_learned < max_learn) {
size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold;
if (available < init_threshold) {
- log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "M) is below initial threshold (" SIZE_FORMAT "M)",
- _gc_times_learned + 1, max_learn, available / M, init_threshold / M);
+ log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "%s) is below initial threshold (" SIZE_FORMAT "%s)",
+ _gc_times_learned + 1, max_learn,
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(init_threshold), proper_unit_for_byte_size(init_threshold));
return true;
}
}
@@ -154,10 +160,15 @@
double allocation_rate = heap->bytes_allocated_since_gc_start() / time_since_last;
if (average_gc > allocation_headroom / allocation_rate) {
- log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.2f MB/s) to deplete free headroom (" SIZE_FORMAT "M)",
- average_gc * 1000, allocation_rate / M, allocation_headroom / M);
- 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);
+ log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s)",
+ average_gc * 1000,
+ byte_size_in_proper_unit(allocation_rate), proper_unit_for_byte_size(allocation_rate),
+ byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom));
+ log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "%s (free) - " SIZE_FORMAT "%s (spike) - " SIZE_FORMAT "%s (penalties) = " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(spike_headroom), proper_unit_for_byte_size(spike_headroom),
+ byte_size_in_proper_unit(penalties), proper_unit_for_byte_size(penalties),
+ byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom));
return true;
}
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -59,21 +59,24 @@
size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
if (available < min_threshold) {
- log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
- available / M, min_threshold / M);
+ log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold));
return true;
}
if (available < threshold_bytes_allocated) {
- log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is lower than allocated recently (" SIZE_FORMAT "M)",
- available / M, threshold_bytes_allocated / M);
+ log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is lower than allocated recently (" SIZE_FORMAT "%s)",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(threshold_bytes_allocated), proper_unit_for_byte_size(threshold_bytes_allocated));
return true;
}
size_t bytes_allocated = heap->bytes_allocated_since_gc_start();
if (bytes_allocated > threshold_bytes_allocated) {
- log_info(gc)("Trigger: Allocated since last cycle (" SIZE_FORMAT "M) is larger than allocation threshold (" SIZE_FORMAT "M)",
- bytes_allocated / M, threshold_bytes_allocated / M);
+ log_info(gc)("Trigger: Allocated since last cycle (" SIZE_FORMAT "%s) is larger than allocation threshold (" SIZE_FORMAT "%s)",
+ byte_size_in_proper_unit(bytes_allocated), proper_unit_for_byte_size(bytes_allocated),
+ byte_size_in_proper_unit(threshold_bytes_allocated), proper_unit_for_byte_size(threshold_bytes_allocated));
return true;
}
@@ -86,8 +89,9 @@
// Do not select too large CSet that would overflow the available free space
size_t max_cset = actual_free * 3 / 4;
- log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M",
- actual_free / M, max_cset / M);
+ log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free),
+ byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset));
size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100;
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -60,8 +60,9 @@
size_t available = MAX2(capacity / 100 * ShenandoahEvacReserve, actual_free);
size_t max_cset = (size_t)(available / ShenandoahEvacWaste);
- log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M",
- actual_free / M, max_cset / M);
+ log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free),
+ byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset));
size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100;
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -57,8 +57,9 @@
size_t threshold_available = capacity / 100 * ShenandoahFreeThreshold;
if (available < threshold_available) {
- log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below free threshold (" SIZE_FORMAT "M)",
- available / M, threshold_available / M);
+ log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below free threshold (" SIZE_FORMAT "%s)",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(threshold_available), proper_unit_for_byte_size(threshold_available));
return true;
}
return ShenandoahHeuristics::should_start_gc();
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -100,9 +100,12 @@
size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0;
size_t max_cset = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste);
- log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "M, Actual Free: "
- SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M, Min Garbage: " SIZE_FORMAT "M",
- free_target / M, actual_free / M, max_cset / M, min_garbage / M);
+ log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "%s, Actual Free: "
+ SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s, Min Garbage: " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(free_target), proper_unit_for_byte_size(free_target),
+ byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free),
+ byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset),
+ byte_size_in_proper_unit(min_garbage), proper_unit_for_byte_size(min_garbage));
// Better select garbage-first regions, and then older ones
QuickSort::sort<RegionData>(data, (int) cnt, compare_by_garbage_then_alloc_seq_ascending, false);
@@ -190,8 +193,9 @@
// anything else.
size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
if (available < min_threshold) {
- log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
- available / M, min_threshold / M);
+ log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold));
return true;
}
@@ -200,8 +204,10 @@
if (_gc_times_learned < max_learn) {
size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold;
if (available < init_threshold) {
- log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "M) is below initial threshold (" SIZE_FORMAT "M)",
- _gc_times_learned + 1, max_learn, available / M, init_threshold / M);
+ log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "%s) is below initial threshold (" SIZE_FORMAT "%s)",
+ _gc_times_learned + 1, max_learn,
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(init_threshold), proper_unit_for_byte_size(init_threshold));
return true;
}
}
@@ -223,10 +229,15 @@
double allocation_rate = heap->bytes_allocated_since_gc_start() / time_since_last;
if (average_gc > allocation_headroom / allocation_rate) {
- log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.2f MB/s) to deplete free headroom (" SIZE_FORMAT "M)",
- average_gc * 1000, allocation_rate / M, allocation_headroom / M);
- 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);
+ log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s)",
+ average_gc * 1000,
+ byte_size_in_proper_unit(allocation_rate), proper_unit_for_byte_size(allocation_rate),
+ byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom));
+ log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "%s (free) - " SIZE_FORMAT "%s (spike) - " SIZE_FORMAT "%s (penalties) = " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(available), proper_unit_for_byte_size(available),
+ byte_size_in_proper_unit(spike_headroom), proper_unit_for_byte_size(spike_headroom),
+ byte_size_in_proper_unit(penalties), proper_unit_for_byte_size(penalties),
+ byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom));
return true;
} else if (ShenandoahHeuristics::should_start_gc()) {
return true;
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -319,13 +319,20 @@
};
void ShenandoahConcurrentMark::update_thread_roots(ShenandoahPhaseTimings::Phase root_phase) {
- WorkGang* workers = _heap->workers();
- bool is_par = workers->active_workers() > 1;
+ assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
+
+ ShenandoahGCPhase phase(root_phase);
+
#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
+
+ WorkGang* workers = _heap->workers();
+ bool is_par = workers->active_workers() > 1;
+
ShenandoahUpdateThreadRootsTask task(is_par, root_phase);
workers->run_task(&task);
+
#if COMPILER2_OR_JVMCI
DerivedPointerTable::update_pointers();
#endif
--- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -491,8 +491,12 @@
size_t max_humongous = max_contig * ShenandoahHeapRegion::region_size_bytes();
size_t free = capacity() - used();
- ls.print("Free: " SIZE_FORMAT "M (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "K, Max humongous: " SIZE_FORMAT "K, ",
- total_free / M, mutator_count(), max / K, max_humongous / K);
+ ls.print("Free: " SIZE_FORMAT "%s (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "%s, Max humongous: " SIZE_FORMAT "%s, ",
+ byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free),
+ mutator_count(),
+ byte_size_in_proper_unit(max), proper_unit_for_byte_size(max),
+ byte_size_in_proper_unit(max_humongous), proper_unit_for_byte_size(max_humongous)
+ );
size_t frag_ext;
if (free > 0) {
@@ -525,8 +529,10 @@
}
}
- ls.print_cr("Evacuation Reserve: " SIZE_FORMAT "M (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "K",
- total_free / M, collector_count(), max / K);
+ ls.print_cr("Evacuation Reserve: " SIZE_FORMAT "%s (" SIZE_FORMAT " regions), Max regular: " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free),
+ collector_count(),
+ byte_size_in_proper_unit(max), proper_unit_for_byte_size(max));
}
}
}
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -522,10 +522,14 @@
void ShenandoahHeap::print_on(outputStream* st) const {
st->print_cr("Shenandoah Heap");
- st->print_cr(" " SIZE_FORMAT "K total, " SIZE_FORMAT "K committed, " SIZE_FORMAT "K used",
- max_capacity() / K, committed() / K, used() / K);
- st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"K regions",
- num_regions(), ShenandoahHeapRegion::region_size_bytes() / K);
+ st->print_cr(" " SIZE_FORMAT "%s total, " SIZE_FORMAT "%s committed, " SIZE_FORMAT "%s used",
+ byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity()),
+ byte_size_in_proper_unit(committed()), proper_unit_for_byte_size(committed()),
+ byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used()));
+ st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"%s regions",
+ num_regions(),
+ byte_size_in_proper_unit(ShenandoahHeapRegion::region_size_bytes()),
+ proper_unit_for_byte_size(ShenandoahHeapRegion::region_size_bytes()));
st->print("Status: ");
if (has_forwarded_objects()) st->print("has forwarded objects, ");
@@ -959,7 +963,7 @@
ShenandoahConcurrentEvacuateRegionObjectClosure cl(_sh);
ShenandoahHeapRegion* r;
while ((r =_cs->claim_next()) != NULL) {
- assert(r->has_live(), "all-garbage regions are reclaimed early");
+ assert(r->has_live(), "Region " SIZE_FORMAT " should have been reclaimed early", r->region_number());
_sh->marked_object_iterate(r, &cl);
if (ShenandoahPacing) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -527,29 +527,35 @@
size_t region_size;
if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) {
if (ShenandoahMinRegionSize > max_heap_size / MIN_NUM_REGIONS) {
- err_msg message("Max heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
- "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "K).",
- max_heap_size/K, MIN_NUM_REGIONS, ShenandoahMinRegionSize/K);
+ err_msg message("Max heap size (" SIZE_FORMAT "%s) is too low to afford the minimum number "
+ "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(max_heap_size), proper_unit_for_byte_size(max_heap_size),
+ MIN_NUM_REGIONS,
+ byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize));
vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message);
}
if (ShenandoahMinRegionSize < MIN_REGION_SIZE) {
- err_msg message("" SIZE_FORMAT "K should not be lower than minimum region size (" SIZE_FORMAT "K).",
- ShenandoahMinRegionSize/K, MIN_REGION_SIZE/K);
+ err_msg message("" SIZE_FORMAT "%s should not be lower than minimum region size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize),
+ byte_size_in_proper_unit(MIN_REGION_SIZE), proper_unit_for_byte_size(MIN_REGION_SIZE));
vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message);
}
if (ShenandoahMinRegionSize < MinTLABSize) {
- err_msg message("" SIZE_FORMAT "K should not be lower than TLAB size size (" SIZE_FORMAT "K).",
- ShenandoahMinRegionSize/K, MinTLABSize/K);
+ err_msg message("" SIZE_FORMAT "%s should not be lower than TLAB size size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize),
+ byte_size_in_proper_unit(MinTLABSize), proper_unit_for_byte_size(MinTLABSize));
vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message);
}
if (ShenandoahMaxRegionSize < MIN_REGION_SIZE) {
- err_msg message("" SIZE_FORMAT "K should not be lower than min region size (" SIZE_FORMAT "K).",
- ShenandoahMaxRegionSize/K, MIN_REGION_SIZE/K);
+ err_msg message("" SIZE_FORMAT "%s should not be lower than min region size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(ShenandoahMaxRegionSize), proper_unit_for_byte_size(ShenandoahMaxRegionSize),
+ byte_size_in_proper_unit(MIN_REGION_SIZE), proper_unit_for_byte_size(MIN_REGION_SIZE));
vm_exit_during_initialization("Invalid -XX:ShenandoahMaxRegionSize option", message);
}
if (ShenandoahMinRegionSize > ShenandoahMaxRegionSize) {
- err_msg message("Minimum (" SIZE_FORMAT "K) should be larger than maximum (" SIZE_FORMAT "K).",
- ShenandoahMinRegionSize/K, ShenandoahMaxRegionSize/K);
+ err_msg message("Minimum (" SIZE_FORMAT "%s) should be larger than maximum (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize),
+ byte_size_in_proper_unit(ShenandoahMaxRegionSize), proper_unit_for_byte_size(ShenandoahMaxRegionSize));
vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize or -XX:ShenandoahMaxRegionSize", message);
}
@@ -563,19 +569,23 @@
} else {
if (ShenandoahHeapRegionSize > max_heap_size / MIN_NUM_REGIONS) {
- err_msg message("Max heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
- "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "K).",
- max_heap_size/K, MIN_NUM_REGIONS, ShenandoahHeapRegionSize/K);
+ err_msg message("Max heap size (" SIZE_FORMAT "%s) is too low to afford the minimum number "
+ "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(max_heap_size), proper_unit_for_byte_size(max_heap_size),
+ MIN_NUM_REGIONS,
+ byte_size_in_proper_unit(ShenandoahHeapRegionSize), proper_unit_for_byte_size(ShenandoahHeapRegionSize));
vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message);
}
if (ShenandoahHeapRegionSize < ShenandoahMinRegionSize) {
- err_msg message("Heap region size (" SIZE_FORMAT "K) should be larger than min region size (" SIZE_FORMAT "K).",
- ShenandoahHeapRegionSize/K, ShenandoahMinRegionSize/K);
+ err_msg message("Heap region size (" SIZE_FORMAT "%s) should be larger than min region size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(ShenandoahHeapRegionSize), proper_unit_for_byte_size(ShenandoahHeapRegionSize),
+ byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize));
vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message);
}
if (ShenandoahHeapRegionSize > ShenandoahMaxRegionSize) {
- err_msg message("Heap region size (" SIZE_FORMAT "K) should be lower than max region size (" SIZE_FORMAT "K).",
- ShenandoahHeapRegionSize/K, ShenandoahMaxRegionSize/K);
+ err_msg message("Heap region size (" SIZE_FORMAT "%s) should be lower than max region size (" SIZE_FORMAT "%s).",
+ byte_size_in_proper_unit(ShenandoahHeapRegionSize), proper_unit_for_byte_size(ShenandoahHeapRegionSize),
+ byte_size_in_proper_unit(ShenandoahMaxRegionSize), proper_unit_for_byte_size(ShenandoahMaxRegionSize));
vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message);
}
region_size = ShenandoahHeapRegionSize;
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -198,7 +198,7 @@
// Macro-properties:
bool is_alloc_allowed() const { return is_empty() || is_regular() || _state == _pinned; }
- bool is_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
+ bool is_stw_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
RegionState state() const { return _state; }
int state_ordinal() const { return region_state_to_ordinal(_state); }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -186,8 +186,9 @@
// given the amount of immediately reclaimable garbage. If we do, figure out the collection set.
assert (immediate_garbage <= total_garbage,
- "Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "M vs " SIZE_FORMAT "M",
- immediate_garbage / M, total_garbage / M);
+ "Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "%s vs " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage),
+ byte_size_in_proper_unit(total_garbage), proper_unit_for_byte_size(total_garbage));
size_t immediate_percent = total_garbage == 0 ? 0 : (immediate_garbage * 100 / total_garbage);
@@ -196,12 +197,16 @@
collection_set->update_region_status();
size_t cset_percent = total_garbage == 0 ? 0 : (collection_set->garbage() * 100 / total_garbage);
- log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "M (" SIZE_FORMAT "%% of total), " SIZE_FORMAT "M CSet, " SIZE_FORMAT " CSet regions",
- collection_set->garbage() / M, cset_percent, collection_set->live_data() / M, collection_set->count());
+ log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s (" SIZE_FORMAT "%% of total), " SIZE_FORMAT "%s CSet, " SIZE_FORMAT " CSet regions",
+ byte_size_in_proper_unit(collection_set->garbage()), proper_unit_for_byte_size(collection_set->garbage()),
+ cset_percent,
+ byte_size_in_proper_unit(collection_set->live_data()), proper_unit_for_byte_size(collection_set->live_data()),
+ collection_set->count());
}
- log_info(gc, ergo)("Immediate Garbage: " SIZE_FORMAT "M (" SIZE_FORMAT "%% of total), " SIZE_FORMAT " regions",
- immediate_garbage / M, immediate_percent, immediate_regions);
+ log_info(gc, ergo)("Immediate Garbage: " SIZE_FORMAT "%s (" SIZE_FORMAT "%% of total), " SIZE_FORMAT " regions",
+ byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage),
+ immediate_percent, immediate_regions);
}
void ShenandoahHeuristics::record_gc_start() {
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -337,7 +337,7 @@
// Can move the region, and this is not the humongous region. Humongous
// moves are special cased here, because their moves are handled separately.
- if (from_region->is_move_allowed() && !from_region->is_humongous()) break;
+ if (from_region->is_stw_move_allowed() && !from_region->is_humongous()) break;
from_region = _heap_regions.next();
}
@@ -345,7 +345,7 @@
if (from_region != NULL) {
assert(slice != NULL, "sanity");
assert(!from_region->is_humongous(), "this path cannot handle humongous regions");
- assert(from_region->is_empty() || from_region->is_move_allowed(), "only regions that can be moved in mark-compact");
+ assert(from_region->is_empty() || from_region->is_stw_move_allowed(), "only regions that can be moved in mark-compact");
slice->add_region(from_region);
}
@@ -419,7 +419,7 @@
continue;
}
- if (r->is_humongous_start() && r->is_move_allowed()) {
+ if (r->is_humongous_start() && r->is_stw_move_allowed()) {
// From-region candidate: movable humongous region
oop old_obj = oop(r->bottom());
size_t words_size = old_obj->size();
@@ -761,7 +761,7 @@
size_t new_start = heap->heap_region_index_containing(old_obj->forwardee());
size_t new_end = new_start + num_regions - 1;
assert(old_start != new_start, "must be real move");
- assert (r->is_move_allowed(), "should be movable");
+ assert(r->is_stw_move_allowed(), "Region " SIZE_FORMAT " should be movable", r->region_number());
Copy::aligned_conjoint_words(heap->get_region(old_start)->bottom(),
heap->get_region(new_start)->bottom(),
--- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -70,9 +70,12 @@
restart_with(non_taxable, tax);
- log_info(gc, ergo)("Pacer for Mark. Expected Live: " SIZE_FORMAT "M, Free: " SIZE_FORMAT
- "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
- live / M, free / M, non_taxable / M, tax);
+ log_info(gc, ergo)("Pacer for Mark. Expected Live: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
+ "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
+ byte_size_in_proper_unit(live), proper_unit_for_byte_size(live),
+ byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
+ byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
+ tax);
}
void ShenandoahPacer::setup_for_evac() {
@@ -91,9 +94,12 @@
restart_with(non_taxable, tax);
- log_info(gc, ergo)("Pacer for Evacuation. Used CSet: " SIZE_FORMAT "M, Free: " SIZE_FORMAT
- "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
- used / M, free / M, non_taxable / M, tax);
+ log_info(gc, ergo)("Pacer for Evacuation. Used CSet: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
+ "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
+ byte_size_in_proper_unit(used), proper_unit_for_byte_size(used),
+ byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
+ byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
+ tax);
}
void ShenandoahPacer::setup_for_updaterefs() {
@@ -112,9 +118,12 @@
restart_with(non_taxable, tax);
- log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "M, Free: " SIZE_FORMAT
- "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
- used / M, free / M, non_taxable / M, tax);
+ log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
+ "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
+ byte_size_in_proper_unit(used), proper_unit_for_byte_size(used),
+ byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
+ byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
+ tax);
}
/*
@@ -136,9 +145,12 @@
restart_with(non_taxable, tax);
- log_info(gc, ergo)("Pacer for Traversal. Expected Live: " SIZE_FORMAT "M, Free: " SIZE_FORMAT
- "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
- live / M, free / M, non_taxable / M, tax);
+ log_info(gc, ergo)("Pacer for Traversal. Expected Live: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
+ "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
+ byte_size_in_proper_unit(live), proper_unit_for_byte_size(live),
+ byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
+ byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
+ tax);
}
/*
@@ -158,8 +170,9 @@
restart_with(initial, tax);
- log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
- initial / M, tax);
+ log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
+ byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial),
+ tax);
}
size_t ShenandoahPacer::update_and_get_progress_history() {
--- a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -205,8 +205,11 @@
void ShenandoahStrDedupQueue::print_statistics_impl() {
Log(gc, stringdedup) log;
log.debug(" Queue:");
- log.debug(" Total buffers: " SIZE_FORMAT " (" SIZE_FORMAT " K). " SIZE_FORMAT " buffers are on free list",
- _total_buffers, (_total_buffers * sizeof(ShenandoahQueueBuffer) / K), _num_free_buffer);
+ log.debug(" Total buffers: " SIZE_FORMAT " (" SIZE_FORMAT " %s). " SIZE_FORMAT " buffers are on free list",
+ _total_buffers,
+ byte_size_in_proper_unit(_total_buffers * sizeof(ShenandoahQueueBuffer)),
+ proper_unit_for_byte_size(_total_buffers * sizeof(ShenandoahQueueBuffer)),
+ _num_free_buffer);
}
class VerifyQueueClosure : public OopClosure {
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -366,8 +366,10 @@
// Rebuild free set
free_set->rebuild();
- log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "M, " SIZE_FORMAT "M CSet, " SIZE_FORMAT " CSet regions",
- collection_set->garbage() / M, collection_set->live_data() / M, collection_set->count());
+ log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s, " SIZE_FORMAT "%s CSet, " SIZE_FORMAT " CSet regions",
+ byte_size_in_proper_unit(collection_set->garbage()), proper_unit_for_byte_size(collection_set->garbage()),
+ byte_size_in_proper_unit(collection_set->live_data()), proper_unit_for_byte_size(collection_set->live_data()),
+ collection_set->count());
}
void ShenandoahTraversalGC::init_traversal_collection() {
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -686,13 +686,17 @@
_heap->heap_region_iterate(&cl);
size_t heap_used = _heap->used();
guarantee(cl.used() == heap_used,
- "%s: heap used size must be consistent: heap-used = " SIZE_FORMAT "K, regions-used = " SIZE_FORMAT "K",
- label, heap_used/K, cl.used()/K);
+ "%s: heap used size must be consistent: heap-used = " SIZE_FORMAT "%s, regions-used = " SIZE_FORMAT "%s",
+ label,
+ byte_size_in_proper_unit(heap_used), proper_unit_for_byte_size(heap_used),
+ byte_size_in_proper_unit(cl.used()), proper_unit_for_byte_size(cl.used()));
size_t heap_committed = _heap->committed();
guarantee(cl.committed() == heap_committed,
- "%s: heap committed size must be consistent: heap-committed = " SIZE_FORMAT "K, regions-committed = " SIZE_FORMAT "K",
- label, heap_committed/K, cl.committed()/K);
+ "%s: heap committed size must be consistent: heap-committed = " SIZE_FORMAT "%s, regions-committed = " SIZE_FORMAT "%s",
+ label,
+ byte_size_in_exact_unit(heap_committed), proper_unit_for_byte_size(heap_committed),
+ byte_size_in_exact_unit(cl.committed()), proper_unit_for_byte_size(cl.committed()));
}
// Internal heap region checks
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -299,11 +299,11 @@
"Should internally-caused GCs invoke concurrent cycles, or go to" \
"stop-the-world (degenerated/full)?") \
\
- experimental(bool, ShenandoahHumongousMoves, true, \
+ diagnostic(bool, ShenandoahHumongousMoves, true, \
"Allow moving humongous regions. This makes GC more resistant " \
"to external fragmentation that may otherwise fail other " \
"humongous allocations, at the expense of higher GC copying " \
- "costs.") \
+ "costs. Currently affects stop-the-world (full) cycle only.") \
\
diagnostic(bool, ShenandoahOOMDuringEvacALot, false, \
"Simulate OOM during evacuation frequently.") \
--- a/src/hotspot/share/gc/z/zLock.inline.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/z/zLock.inline.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -80,12 +80,16 @@
template <typename T>
inline ZLocker<T>::ZLocker(T* lock) :
_lock(lock) {
- _lock->lock();
+ if (_lock != NULL) {
+ _lock->lock();
+ }
}
template <typename T>
inline ZLocker<T>::~ZLocker() {
- _lock->unlock();
+ if (_lock != NULL) {
+ _lock->unlock();
+ }
}
#endif // SHARE_GC_Z_ZLOCK_INLINE_HPP
--- a/src/hotspot/share/gc/z/zNMethodTable.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/z/zNMethodTable.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -51,7 +51,7 @@
size_t ZNMethodTable::_nregistered = 0;
size_t ZNMethodTable::_nunregistered = 0;
ZNMethodTableIteration ZNMethodTable::_iteration;
-ZSafeDelete<ZNMethodTableEntry[]> ZNMethodTable::_safe_delete;
+ZSafeDeleteNoLock<ZNMethodTableEntry[]> ZNMethodTable::_safe_delete;
size_t ZNMethodTable::first_index(const nmethod* nm, size_t size) {
assert(is_power_of_2(size), "Invalid size");
--- a/src/hotspot/share/gc/z/zNMethodTable.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/z/zNMethodTable.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -35,12 +35,12 @@
class ZNMethodTable : public AllStatic {
private:
- static ZNMethodTableEntry* _table;
- static size_t _size;
- static size_t _nregistered;
- static size_t _nunregistered;
- static ZNMethodTableIteration _iteration;
- static ZSafeDelete<ZNMethodTableEntry[]> _safe_delete;
+ static ZNMethodTableEntry* _table;
+ static size_t _size;
+ static size_t _nregistered;
+ static size_t _nunregistered;
+ static ZNMethodTableIteration _iteration;
+ static ZSafeDeleteNoLock<ZNMethodTableEntry[]> _safe_delete;
static ZNMethodTableEntry* create(size_t size);
static void destroy(ZNMethodTableEntry* table);
--- a/src/hotspot/share/gc/z/zSafeDelete.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/z/zSafeDelete.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -29,11 +29,11 @@
#include "metaprogramming/removeExtent.hpp"
template <typename T>
-class ZSafeDelete {
+class ZSafeDeleteImpl {
private:
typedef typename RemoveExtent<T>::type ItemT;
- ZLock _lock;
+ ZLock* _lock;
uint64_t _enabled;
ZArray<ItemT*> _deferred;
@@ -41,7 +41,7 @@
void immediate_delete(ItemT* item);
public:
- ZSafeDelete();
+ ZSafeDeleteImpl(ZLock* lock);
void enable_deferred_delete();
void disable_deferred_delete();
@@ -49,4 +49,19 @@
void operator()(ItemT* item);
};
+template <typename T>
+class ZSafeDelete : public ZSafeDeleteImpl<T> {
+private:
+ ZLock _lock;
+
+public:
+ ZSafeDelete();
+};
+
+template <typename T>
+class ZSafeDeleteNoLock : public ZSafeDeleteImpl<T> {
+public:
+ ZSafeDeleteNoLock();
+};
+
#endif // SHARE_GC_Z_ZSAFEDELETE_HPP
--- a/src/hotspot/share/gc/z/zSafeDelete.inline.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/z/zSafeDelete.inline.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -30,14 +30,14 @@
#include "utilities/debug.hpp"
template <typename T>
-ZSafeDelete<T>::ZSafeDelete() :
- _lock(),
+ZSafeDeleteImpl<T>::ZSafeDeleteImpl(ZLock* lock) :
+ _lock(lock),
_enabled(0),
_deferred() {}
template <typename T>
-bool ZSafeDelete<T>::deferred_delete(ItemT* item) {
- ZLocker<ZLock> locker(&_lock);
+bool ZSafeDeleteImpl<T>::deferred_delete(ItemT* item) {
+ ZLocker<ZLock> locker(_lock);
if (_enabled > 0) {
_deferred.add(item);
return true;
@@ -47,7 +47,7 @@
}
template <typename T>
-void ZSafeDelete<T>::immediate_delete(ItemT* item) {
+void ZSafeDeleteImpl<T>::immediate_delete(ItemT* item) {
if (IsArray<T>::value) {
delete [] item;
} else {
@@ -56,17 +56,17 @@
}
template <typename T>
-void ZSafeDelete<T>::enable_deferred_delete() {
- ZLocker<ZLock> locker(&_lock);
+void ZSafeDeleteImpl<T>::enable_deferred_delete() {
+ ZLocker<ZLock> locker(_lock);
_enabled++;
}
template <typename T>
-void ZSafeDelete<T>::disable_deferred_delete() {
+void ZSafeDeleteImpl<T>::disable_deferred_delete() {
ZArray<ItemT*> deferred;
{
- ZLocker<ZLock> locker(&_lock);
+ ZLocker<ZLock> locker(_lock);
assert(_enabled > 0, "Invalid state");
if (--_enabled == 0) {
deferred.transfer(&_deferred);
@@ -80,10 +80,19 @@
}
template <typename T>
-void ZSafeDelete<T>::operator()(ItemT* item) {
+void ZSafeDeleteImpl<T>::operator()(ItemT* item) {
if (!deferred_delete(item)) {
immediate_delete(item);
}
}
+template <typename T>
+ZSafeDelete<T>::ZSafeDelete() :
+ ZSafeDeleteImpl<T>(&_lock),
+ _lock() {}
+
+template <typename T>
+ZSafeDeleteNoLock<T>::ZSafeDeleteNoLock() :
+ ZSafeDeleteImpl<T>(NULL) {}
+
#endif // SHARE_GC_Z_ZSAFEDELETE_INLINE_HPP
--- a/src/hotspot/share/gc/z/z_globals.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/gc/z/z_globals.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -86,9 +86,6 @@
"Verify marking stacks") \
\
diagnostic(bool, ZVerifyForwarding, false, \
- "Verify forwarding tables") \
- \
- develop(bool, ZVerifyLoadBarriers, false, \
- "Verify that reference loads are followed by barriers")
+ "Verify forwarding tables")
#endif // SHARE_GC_Z_Z_GLOBALS_HPP
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -28,6 +28,7 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/barrierSetNMethod.hpp"
@@ -52,7 +53,6 @@
#include "prims/nativeLookup.hpp"
#include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/frame.inline.hpp"
--- a/src/hotspot/share/interpreter/linkResolver.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/interpreter/linkResolver.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -30,6 +30,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/bootstrapInfo.hpp"
@@ -48,7 +49,6 @@
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "prims/nativeLookup.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/jvmci/compilerRuntime.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/jvmci/compilerRuntime.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -25,11 +25,11 @@
#include "aot/aotLoader.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "interpreter/linkResolver.hpp"
#include "jvmci/compilerRuntime.hpp"
#include "oops/cpCache.inline.hpp"
#include "oops/oop.inline.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -642,11 +642,9 @@
failed_speculations, speculations, speculations_len);
cb = nm->as_codeblob_or_null();
if (nm != NULL && compile_state == NULL) {
+ // This compile didn't come through the CompileBroker so perform the printing here
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
- bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption;
- if (!printnmethods && (PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers)) {
- nm->print_nmethod(printnmethods);
- }
+ nm->maybe_print_nmethod(directive);
DirectivesStack::release(directive);
}
}
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -31,6 +31,7 @@
#include "jvmci/vmStructs_jvmci.hpp"
#include "memory/universe.hpp"
#include "oops/compressedOops.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/resourceHash.hpp"
--- a/src/hotspot/share/oops/instanceKlass.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/instanceKlass.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -992,7 +992,6 @@
void process_interfaces(Thread *thread);
// virtual operations from Klass
- bool is_leaf_class() const { return _subklass == NULL; }
GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots,
Array<InstanceKlass*>* transitive_interfaces);
bool can_be_primary_super_slow() const;
--- a/src/hotspot/share/oops/klass.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/klass.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -57,10 +57,6 @@
_java_mirror = class_loader_data()->add_handle(m);
}
-oop Klass::java_mirror() const {
- return _java_mirror.resolve();
-}
-
oop Klass::java_mirror_no_keepalive() const {
return _java_mirror.peek();
}
@@ -681,8 +677,6 @@
}
}
-oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
-
// In product mode, this function doesn't have virtual function calls so
// there might be some performance advantage to handling InstanceKlass here.
const char* Klass::external_name() const {
@@ -826,14 +820,6 @@
return ClassLoaderDataGraph::is_valid(k->class_loader_data());
}
-klassVtable Klass::vtable() const {
- return klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
-}
-
-vtableEntry* Klass::start_of_vtable() const {
- return (vtableEntry*) ((address)this + in_bytes(vtable_start_offset()));
-}
-
Method* Klass::method_at_vtable(int index) {
#ifndef PRODUCT
assert(index >= 0, "valid vtable index");
@@ -844,9 +830,6 @@
return start_of_vtable()[index].method();
}
-ByteSize Klass::vtable_start_offset() {
- return in_ByteSize(InstanceKlass::header_size() * wordSize);
-}
#ifndef PRODUCT
--- a/src/hotspot/share/oops/klass.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/klass.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -469,8 +469,6 @@
virtual bool should_be_initialized() const { return false; }
// initializes the klass
virtual void initialize(TRAPS);
- // lookup operation for MethodLookupCache
- friend class MethodLookupCache;
virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature,
OverpassLookupMode overpass_mode,
@@ -537,9 +535,6 @@
}
public:
- // subclass accessor (here for convenience; undefined for non-klass objects)
- virtual bool is_leaf_class() const { fatal("not a class"); return false; }
- public:
// ALL FUNCTIONS BELOW THIS POINT ARE DISPATCHED FROM AN OOP
// These functions describe behavior for the oop not the KLASS.
--- a/src/hotspot/share/oops/klass.inline.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/klass.inline.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -25,13 +25,35 @@
#ifndef SHARE_OOPS_KLASS_INLINE_HPP
#define SHARE_OOPS_KLASS_INLINE_HPP
+#include "classfile/classLoaderData.inline.hpp"
#include "oops/compressedOops.hpp"
#include "oops/klass.hpp"
#include "oops/markWord.hpp"
+#include "oops/oopHandle.inline.hpp"
inline void Klass::set_prototype_header(markWord header) {
assert(!header.has_bias_pattern() || is_instance_klass(), "biased locking currently only supported for Java instances");
_prototype_header = header;
}
+inline oop Klass::java_mirror() const {
+ return _java_mirror.resolve();
+}
+
+inline klassVtable Klass::vtable() const {
+ return klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
+}
+
+inline oop Klass::class_loader() const {
+ return class_loader_data()->class_loader();
+}
+
+inline vtableEntry* Klass::start_of_vtable() const {
+ return (vtableEntry*) ((address)this + in_bytes(vtable_start_offset()));
+}
+
+inline ByteSize Klass::vtable_start_offset() {
+ return in_ByteSize(InstanceKlass::header_size() * wordSize);
+}
+
#endif // SHARE_OOPS_KLASS_INLINE_HPP
--- a/src/hotspot/share/oops/klassVtable.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/klassVtable.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -1501,7 +1501,6 @@
#endif
void vtableEntry::verify(klassVtable* vt, outputStream* st) {
- NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true));
Klass* vtklass = vt->klass();
if (vtklass->is_instance_klass() &&
(InstanceKlass::cast(vtklass)->major_version() >= klassVtable::VTABLE_TRANSITIVE_OVERRIDE_VERSION)) {
--- a/src/hotspot/share/oops/method.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/method.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -28,6 +28,7 @@
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "code/debugInfoRec.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/bytecodeTracer.hpp"
@@ -54,7 +55,6 @@
#include "prims/methodHandles.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/arguments.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
--- a/src/hotspot/share/oops/methodData.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/oops/methodData.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compilerOracle.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/bytecodeStream.hpp"
@@ -34,7 +35,6 @@
#include "oops/methodData.inline.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/arguments.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/orderAccess.hpp"
--- a/src/hotspot/share/opto/buildOopMap.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/opto/buildOopMap.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -352,7 +352,6 @@
} else {
// Other - some reaching non-oop value
- omap->set_value( r);
#ifdef ASSERT
if( t->isa_rawptr() && C->cfg()->_raw_oops.member(def) ) {
def->dump();
@@ -377,11 +376,18 @@
#endif
#ifdef ASSERT
- for( OopMapStream oms1(omap, OopMapValue::derived_oop_value); !oms1.is_done(); oms1.next()) {
+ for( OopMapStream oms1(omap); !oms1.is_done(); oms1.next()) {
OopMapValue omv1 = oms1.current();
+ if (omv1.type() != OopMapValue::derived_oop_value) {
+ continue;
+ }
bool found = false;
- for( OopMapStream oms2(omap,OopMapValue::oop_value); !oms2.is_done(); oms2.next()) {
- if( omv1.content_reg() == oms2.current().reg() ) {
+ for( OopMapStream oms2(omap); !oms2.is_done(); oms2.next()) {
+ OopMapValue omv2 = oms2.current();
+ if (omv2.type() != OopMapValue::oop_value) {
+ continue;
+ }
+ if( omv1.content_reg() == omv2.reg() ) {
found = true;
break;
}
--- a/src/hotspot/share/opto/library_call.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/opto/library_call.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "gc/shared/barrierSet.hpp"
#include "jfr/support/jfrIntrinsics.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "opto/addnode.hpp"
#include "opto/arraycopynode.hpp"
--- a/src/hotspot/share/opto/loopTransform.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/opto/loopTransform.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -3129,6 +3129,13 @@
// We also need to replace the original limit to collapse loop exit.
Node* cmp = cl->loopexit()->cmp_node();
assert(cl->limit() == cmp->in(2), "sanity");
+ // Duplicate cmp node if it has other users
+ if (cmp->outcnt() > 1) {
+ cmp = cmp->clone();
+ cmp = phase->_igvn.register_new_node_with_optimizer(cmp);
+ BoolNode *bol = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool();
+ phase->_igvn.replace_input_of(bol, 1, cmp); // put bol on worklist
+ }
phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist
phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist
}
--- a/src/hotspot/share/prims/jni.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/prims/jni.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -65,7 +65,6 @@
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
@@ -88,6 +87,9 @@
#include "utilities/histogram.hpp"
#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciCompiler.hpp"
+#endif
static jint CurrentVersion = JNI_VERSION_10;
--- a/src/hotspot/share/prims/jniCheck.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/prims/jniCheck.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -534,10 +534,10 @@
if (obj != NULL) {
oop recv = jniCheck::validate_object(thr, obj);
assert(recv != NULL, "validate_object checks that");
- Klass* ik = recv->klass();
+ Klass* rk = recv->klass();
// Check that the object is a subtype of method holder too.
- if (!InstanceKlass::cast(ik)->is_subtype_of(holder)) {
+ if (!rk->is_subtype_of(holder)) {
ReportJNIFatalError(thr, fatal_wrong_class_or_method);
}
}
--- a/src/hotspot/share/prims/methodHandles.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/prims/methodHandles.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -41,7 +41,6 @@
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "prims/methodHandles.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/prims/whitebox.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/prims/whitebox.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "code/codeCache.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/methodMatcher.hpp"
#include "compiler/directivesParser.hpp"
#include "gc/shared/gcConfig.hpp"
@@ -58,7 +59,6 @@
#include "prims/wbtestmethods/parserTests.hpp"
#include "prims/whitebox.inline.hpp"
#include "runtime/arguments.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/flags/jvmFlag.hpp"
--- a/src/hotspot/share/runtime/compilationPolicy.cpp Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,506 +0,0 @@
-/*
- * 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
- * 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/classLoaderDataGraph.inline.hpp"
-#include "code/compiledIC.hpp"
-#include "code/nmethod.hpp"
-#include "code/scopeDesc.hpp"
-#include "interpreter/interpreter.hpp"
-#include "memory/resourceArea.hpp"
-#include "oops/methodData.hpp"
-#include "oops/method.inline.hpp"
-#include "oops/oop.inline.hpp"
-#include "prims/nativeLookup.hpp"
-#include "runtime/compilationPolicy.hpp"
-#include "runtime/frame.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/stubRoutines.hpp"
-#include "runtime/thread.hpp"
-#include "runtime/tieredThresholdPolicy.hpp"
-#include "runtime/vframe.hpp"
-#include "runtime/vmOperations.hpp"
-#include "utilities/events.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-#ifdef COMPILER1
-#include "c1/c1_Compiler.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2compiler.hpp"
-#endif
-
-CompilationPolicy* CompilationPolicy::_policy;
-
-// Determine compilation policy based on command line argument
-void compilationPolicy_init() {
- #ifdef TIERED
- if (TieredCompilation) {
- CompilationPolicy::set_policy(new TieredThresholdPolicy());
- } else {
- CompilationPolicy::set_policy(new SimpleCompPolicy());
- }
- #else
- CompilationPolicy::set_policy(new SimpleCompPolicy());
- #endif
-
- CompilationPolicy::policy()->initialize();
-}
-
-// Returns true if m must be compiled before executing it
-// This is intended to force compiles for methods (usually for
-// debugging) that would otherwise be interpreted for some reason.
-bool CompilationPolicy::must_be_compiled(const methodHandle& m, int comp_level) {
- // Don't allow Xcomp to cause compiles in replay mode
- if (ReplayCompiles) return false;
-
- if (m->has_compiled_code()) return false; // already compiled
- if (!can_be_compiled(m, comp_level)) return false;
-
- return !UseInterpreter || // must compile all methods
- (UseCompiler && AlwaysCompileLoopMethods && m->has_loops() && CompileBroker::should_compile_new_jobs()); // eagerly compile loop methods
-}
-
-void CompilationPolicy::compile_if_required(const methodHandle& selected_method, TRAPS) {
- if (must_be_compiled(selected_method)) {
- // This path is unusual, mostly used by the '-Xcomp' stress test mode.
-
- // Note: with several active threads, the must_be_compiled may be true
- // while can_be_compiled is false; remove assert
- // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile");
- if (!THREAD->can_call_java() || THREAD->is_Compiler_thread()) {
- // don't force compilation, resolve was on behalf of compiler
- return;
- }
- if (selected_method->method_holder()->is_not_initialized()) {
- // 'is_not_initialized' means not only '!is_initialized', but also that
- // initialization has not been started yet ('!being_initialized')
- // Do not force compilation of methods in uninitialized classes.
- // Note that doing this would throw an assert later,
- // in CompileBroker::compile_method.
- // We sometimes use the link resolver to do reflective lookups
- // even before classes are initialized.
- return;
- }
- CompileBroker::compile_method(selected_method, InvocationEntryBci,
- CompilationPolicy::policy()->initial_compile_level(),
- methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
- }
-}
-
-// Returns true if m is allowed to be compiled
-bool CompilationPolicy::can_be_compiled(const methodHandle& m, int comp_level) {
- // allow any levels for WhiteBox
- assert(WhiteBoxAPI || comp_level == CompLevel_all || is_compile(comp_level), "illegal compilation level");
-
- if (m->is_abstract()) return false;
- if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false;
-
- // Math intrinsics should never be compiled as this can lead to
- // monotonicity problems because the interpreter will prefer the
- // compiled code to the intrinsic version. This can't happen in
- // production because the invocation counter can't be incremented
- // but we shouldn't expose the system to this problem in testing
- // modes.
- if (!AbstractInterpreter::can_be_compiled(m)) {
- return false;
- }
- if (comp_level == CompLevel_all) {
- if (TieredCompilation) {
- // enough to be compilable at any level for tiered
- return !m->is_not_compilable(CompLevel_simple) || !m->is_not_compilable(CompLevel_full_optimization);
- } else {
- // must be compilable at available level for non-tiered
- return !m->is_not_compilable(CompLevel_highest_tier);
- }
- } else if (is_compile(comp_level)) {
- return !m->is_not_compilable(comp_level);
- }
- return false;
-}
-
-// Returns true if m is allowed to be osr compiled
-bool CompilationPolicy::can_be_osr_compiled(const methodHandle& m, int comp_level) {
- bool result = false;
- if (comp_level == CompLevel_all) {
- if (TieredCompilation) {
- // enough to be osr compilable at any level for tiered
- result = !m->is_not_osr_compilable(CompLevel_simple) || !m->is_not_osr_compilable(CompLevel_full_optimization);
- } else {
- // must be osr compilable at available level for non-tiered
- result = !m->is_not_osr_compilable(CompLevel_highest_tier);
- }
- } else if (is_compile(comp_level)) {
- result = !m->is_not_osr_compilable(comp_level);
- }
- return (result && can_be_compiled(m, comp_level));
-}
-
-bool CompilationPolicy::is_compilation_enabled() {
- // NOTE: CompileBroker::should_compile_new_jobs() checks for UseCompiler
- return CompileBroker::should_compile_new_jobs();
-}
-
-CompileTask* CompilationPolicy::select_task_helper(CompileQueue* compile_queue) {
- // Remove unloaded methods from the queue
- for (CompileTask* task = compile_queue->first(); task != NULL; ) {
- CompileTask* next = task->next();
- if (task->is_unloaded()) {
- compile_queue->remove_and_mark_stale(task);
- }
- task = next;
- }
-#if INCLUDE_JVMCI
- if (UseJVMCICompiler && !BackgroundCompilation) {
- /*
- * In blocking compilation mode, the CompileBroker will make
- * compilations submitted by a JVMCI compiler thread non-blocking. These
- * compilations should be scheduled after all blocking compilations
- * to service non-compiler related compilations sooner and reduce the
- * chance of such compilations timing out.
- */
- for (CompileTask* task = compile_queue->first(); task != NULL; task = task->next()) {
- if (task->is_blocking()) {
- return task;
- }
- }
- }
-#endif
- return compile_queue->first();
-}
-
-#ifndef PRODUCT
-void SimpleCompPolicy::trace_osr_completion(nmethod* osr_nm) {
- if (TraceOnStackReplacement) {
- if (osr_nm == NULL) tty->print_cr("compilation failed");
- else tty->print_cr("nmethod " INTPTR_FORMAT, p2i(osr_nm));
- }
-}
-#endif // !PRODUCT
-
-void SimpleCompPolicy::initialize() {
- // Setup the compiler thread numbers
- if (CICompilerCountPerCPU) {
- // Example: if CICompilerCountPerCPU is true, then we get
- // max(log2(8)-1,1) = 2 compiler threads on an 8-way machine.
- // May help big-app startup time.
- _compiler_count = MAX2(log2_int(os::active_processor_count())-1,1);
- // Make sure there is enough space in the code cache to hold all the compiler buffers
- size_t buffer_size = 1;
-#ifdef COMPILER1
- buffer_size = is_client_compilation_mode_vm() ? Compiler::code_buffer_size() : buffer_size;
-#endif
-#ifdef COMPILER2
- buffer_size = is_server_compilation_mode_vm() ? C2Compiler::initial_code_buffer_size() : buffer_size;
-#endif
- int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size;
- if (_compiler_count > max_count) {
- // Lower the compiler count such that all buffers fit into the code cache
- _compiler_count = MAX2(max_count, 1);
- }
- FLAG_SET_ERGO(CICompilerCount, _compiler_count);
- } else {
- _compiler_count = CICompilerCount;
- }
-}
-
-// Note: this policy is used ONLY if TieredCompilation is off.
-// compiler_count() behaves the following way:
-// - with TIERED build (with both COMPILER1 and COMPILER2 defined) it should return
-// zero for the c1 compilation levels in server compilation mode runs
-// and c2 compilation levels in client compilation mode runs.
-// - with COMPILER2 not defined it should return zero for c2 compilation levels.
-// - with COMPILER1 not defined it should return zero for c1 compilation levels.
-// - if neither is defined - always return zero.
-int SimpleCompPolicy::compiler_count(CompLevel comp_level) {
- assert(!TieredCompilation, "This policy should not be used with TieredCompilation");
- if (COMPILER2_PRESENT(is_server_compilation_mode_vm() && is_c2_compile(comp_level) ||)
- is_client_compilation_mode_vm() && is_c1_compile(comp_level)) {
- return _compiler_count;
- }
- return 0;
-}
-
-void SimpleCompPolicy::reset_counter_for_invocation_event(const methodHandle& m) {
- // Make sure invocation and backedge counter doesn't overflow again right away
- // as would be the case for native methods.
-
- // BUT also make sure the method doesn't look like it was never executed.
- // Set carry bit and reduce counter's value to min(count, CompileThreshold/2).
- MethodCounters* mcs = m->method_counters();
- assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
- mcs->invocation_counter()->set_carry();
- mcs->backedge_counter()->set_carry();
-
- assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
-}
-
-void SimpleCompPolicy::reset_counter_for_back_branch_event(const methodHandle& m) {
- // Delay next back-branch event but pump up invocation counter to trigger
- // whole method compilation.
- MethodCounters* mcs = m->method_counters();
- assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
- InvocationCounter* i = mcs->invocation_counter();
- InvocationCounter* b = mcs->backedge_counter();
-
- // Don't set invocation_counter's value too low otherwise the method will
- // look like immature (ic < ~5300) which prevents the inlining based on
- // the type profiling.
- i->set(i->state(), CompileThreshold);
- // Don't reset counter too low - it is used to check if OSR method is ready.
- b->set(b->state(), CompileThreshold / 2);
-}
-
-//
-// CounterDecay
-//
-// Iterates through invocation counters and decrements them. This
-// is done at each safepoint.
-//
-class CounterDecay : public AllStatic {
- static jlong _last_timestamp;
- static void do_method(Method* m) {
- MethodCounters* mcs = m->method_counters();
- if (mcs != NULL) {
- mcs->invocation_counter()->decay();
- }
- }
-public:
- static void decay();
- static bool is_decay_needed() {
- return (os::javaTimeMillis() - _last_timestamp) > CounterDecayMinIntervalLength;
- }
-};
-
-jlong CounterDecay::_last_timestamp = 0;
-
-void CounterDecay::decay() {
- _last_timestamp = os::javaTimeMillis();
-
- // This operation is going to be performed only at the end of a safepoint
- // and hence GC's will not be going on, all Java mutators are suspended
- // at this point and hence SystemDictionary_lock is also not needed.
- assert(SafepointSynchronize::is_at_safepoint(), "can only be executed at a safepoint");
- size_t nclasses = ClassLoaderDataGraph::num_instance_classes();
- size_t classes_per_tick = nclasses * (CounterDecayMinIntervalLength * 1e-3 /
- CounterHalfLifeTime);
- for (size_t i = 0; i < classes_per_tick; i++) {
- InstanceKlass* k = ClassLoaderDataGraph::try_get_next_class();
- if (k != NULL) {
- k->methods_do(do_method);
- }
- }
-}
-
-// Called at the end of the safepoint
-void SimpleCompPolicy::do_safepoint_work() {
- if(UseCounterDecay && CounterDecay::is_decay_needed()) {
- CounterDecay::decay();
- }
-}
-
-void SimpleCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
- ScopeDesc* sd = trap_scope;
- MethodCounters* mcs;
- InvocationCounter* c;
- for (; !sd->is_top(); sd = sd->sender()) {
- mcs = sd->method()->method_counters();
- if (mcs != NULL) {
- // Reset ICs of inlined methods, since they can trigger compilations also.
- mcs->invocation_counter()->reset();
- }
- }
- mcs = sd->method()->method_counters();
- if (mcs != NULL) {
- c = mcs->invocation_counter();
- if (is_osr) {
- // It was an OSR method, so bump the count higher.
- c->set(c->state(), CompileThreshold);
- } else {
- c->reset();
- }
- mcs->backedge_counter()->reset();
- }
-}
-
-// This method can be called by any component of the runtime to notify the policy
-// that it's recommended to delay the compilation of this method.
-void SimpleCompPolicy::delay_compilation(Method* method) {
- MethodCounters* mcs = method->method_counters();
- if (mcs != NULL) {
- mcs->invocation_counter()->decay();
- mcs->backedge_counter()->decay();
- }
-}
-
-void SimpleCompPolicy::disable_compilation(Method* method) {
- MethodCounters* mcs = method->method_counters();
- if (mcs != NULL) {
- mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
- mcs->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
- }
-}
-
-CompileTask* SimpleCompPolicy::select_task(CompileQueue* compile_queue) {
- return select_task_helper(compile_queue);
-}
-
-bool SimpleCompPolicy::is_mature(Method* method) {
- MethodData* mdo = method->method_data();
- assert(mdo != NULL, "Should be");
- uint current = mdo->mileage_of(method);
- uint initial = mdo->creation_mileage();
- if (current < initial)
- return true; // some sort of overflow
- uint target;
- if (ProfileMaturityPercentage <= 0)
- target = (uint) -ProfileMaturityPercentage; // absolute value
- else
- target = (uint)( (ProfileMaturityPercentage * CompileThreshold) / 100 );
- return (current >= initial + target);
-}
-
-nmethod* SimpleCompPolicy::event(const methodHandle& method, const methodHandle& inlinee, int branch_bci,
- int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
- assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
- NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
- if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
- // If certain JVMTI events (e.g. frame pop event) are requested then the
- // thread is forced to remain in interpreted code. This is
- // implemented partly by a check in the run_compiled_code
- // section of the interpreter whether we should skip running
- // compiled code, and partly by skipping OSR compiles for
- // interpreted-only threads.
- if (bci != InvocationEntryBci) {
- reset_counter_for_back_branch_event(method);
- return NULL;
- }
- }
- if (ReplayCompiles) {
- // Don't trigger other compiles in testing mode
- if (bci == InvocationEntryBci) {
- reset_counter_for_invocation_event(method);
- } else {
- reset_counter_for_back_branch_event(method);
- }
- return NULL;
- }
-
- if (bci == InvocationEntryBci) {
- // when code cache is full, compilation gets switched off, UseCompiler
- // is set to false
- if (!method->has_compiled_code() && UseCompiler) {
- method_invocation_event(method, thread);
- } else {
- // Force counter overflow on method entry, even if no compilation
- // happened. (The method_invocation_event call does this also.)
- reset_counter_for_invocation_event(method);
- }
- // compilation at an invocation overflow no longer goes and retries test for
- // compiled method. We always run the loser of the race as interpreted.
- // so return NULL
- return NULL;
- } else {
- // counter overflow in a loop => try to do on-stack-replacement
- nmethod* osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
- NOT_PRODUCT(trace_osr_request(method, osr_nm, bci));
- // when code cache is full, we should not compile any more...
- if (osr_nm == NULL && UseCompiler) {
- method_back_branch_event(method, bci, thread);
- osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
- }
- if (osr_nm == NULL) {
- reset_counter_for_back_branch_event(method);
- return NULL;
- }
- return osr_nm;
- }
- return NULL;
-}
-
-#ifndef PRODUCT
-void SimpleCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) {
- if (TraceInvocationCounterOverflow) {
- MethodCounters* mcs = m->method_counters();
- assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
- InvocationCounter* ic = mcs->invocation_counter();
- InvocationCounter* bc = mcs->backedge_counter();
- ResourceMark rm;
- if (bci == InvocationEntryBci) {
- tty->print("comp-policy cntr ovfl @ %d in entry of ", bci);
- } else {
- tty->print("comp-policy cntr ovfl @ %d in loop of ", bci);
- }
- m->print_value();
- tty->cr();
- ic->print();
- bc->print();
- if (ProfileInterpreter) {
- if (bci != InvocationEntryBci) {
- MethodData* mdo = m->method_data();
- if (mdo != NULL) {
- ProfileData *pd = mdo->bci_to_data(branch_bci);
- if (pd == NULL) {
- tty->print_cr("back branch count = N/A (missing ProfileData)");
- } else {
- tty->print_cr("back branch count = %d", pd->as_JumpData()->taken());
- }
- }
- }
- }
- }
-}
-
-void SimpleCompPolicy::trace_osr_request(const methodHandle& method, nmethod* osr, int bci) {
- if (TraceOnStackReplacement) {
- ResourceMark rm;
- tty->print(osr != NULL ? "Reused OSR entry for " : "Requesting OSR entry for ");
- method->print_short_name(tty);
- tty->print_cr(" at bci %d", bci);
- }
-}
-#endif // !PRODUCT
-
-void SimpleCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) {
- const int comp_level = CompLevel_highest_tier;
- const int hot_count = m->invocation_count();
- reset_counter_for_invocation_event(m);
-
- if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
- CompiledMethod* nm = m->code();
- if (nm == NULL ) {
- CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, CompileTask::Reason_InvocationCount, thread);
- }
- }
-}
-
-void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
- const int comp_level = CompLevel_highest_tier;
- const int hot_count = m->backedge_count();
-
- if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
- CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, thread);
- NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
- }
-}
--- a/src/hotspot/share/runtime/compilationPolicy.hpp Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * 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
- * 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_RUNTIME_COMPILATIONPOLICY_HPP
-#define SHARE_RUNTIME_COMPILATIONPOLICY_HPP
-
-#include "code/nmethod.hpp"
-#include "compiler/compileBroker.hpp"
-#include "memory/allocation.hpp"
-#include "runtime/vmOperations.hpp"
-#include "utilities/growableArray.hpp"
-
-// The CompilationPolicy selects which method (if any) should be compiled.
-// It also decides which methods must always be compiled (i.e., are never
-// interpreted).
-class CompileTask;
-class CompileQueue;
-
-class CompilationPolicy : public CHeapObj<mtCompiler> {
- static CompilationPolicy* _policy;
-
- // m must be compiled before executing it
- static bool must_be_compiled(const methodHandle& m, int comp_level = CompLevel_all);
-
-public:
- // If m must_be_compiled then request a compilation from the CompileBroker.
- // This supports the -Xcomp option.
- static void compile_if_required(const methodHandle& m, TRAPS);
-
- // m is allowed to be compiled
- static bool can_be_compiled(const methodHandle& m, int comp_level = CompLevel_all);
- // m is allowed to be osr compiled
- static bool can_be_osr_compiled(const methodHandle& m, int comp_level = CompLevel_all);
- static bool is_compilation_enabled();
- static void set_policy(CompilationPolicy* policy) { _policy = policy; }
- static CompilationPolicy* policy() { return _policy; }
-
- static CompileTask* select_task_helper(CompileQueue* compile_queue);
-
- // Return initial compile level that is used with Xcomp
- virtual CompLevel initial_compile_level() = 0;
- virtual int compiler_count(CompLevel comp_level) = 0;
- // main notification entry, return a pointer to an nmethod if the OSR is required,
- // returns NULL otherwise.
- virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) = 0;
- // safepoint() is called at the end of the safepoint
- virtual void do_safepoint_work() = 0;
- // reprofile request
- virtual void reprofile(ScopeDesc* trap_scope, bool is_osr) = 0;
- // delay_compilation(method) can be called by any component of the runtime to notify the policy
- // that it's recommended to delay the compilation of this method.
- virtual void delay_compilation(Method* method) = 0;
- // disable_compilation() is called whenever the runtime decides to disable compilation of the
- // specified method.
- virtual void disable_compilation(Method* method) = 0;
- // Select task is called by CompileBroker. The queue is guaranteed to have at least one
- // element and is locked. The function should select one and return it.
- virtual CompileTask* select_task(CompileQueue* compile_queue) = 0;
- // Tell the runtime if we think a given method is adequately profiled.
- virtual bool is_mature(Method* method) = 0;
- // Do policy initialization
- virtual void initialize() = 0;
- virtual bool should_not_inline(ciEnv* env, ciMethod* method) { return false; }
-};
-
-// A simple compilation policy.
-class SimpleCompPolicy : public CompilationPolicy {
- int _compiler_count;
- private:
- static void trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci);
- static void trace_osr_request(const methodHandle& method, nmethod* osr, int bci);
- static void trace_osr_completion(nmethod* osr_nm);
- void reset_counter_for_invocation_event(const methodHandle& method);
- void reset_counter_for_back_branch_event(const methodHandle& method);
- void method_invocation_event(const methodHandle& m, JavaThread* thread);
- void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
- public:
- SimpleCompPolicy() : _compiler_count(0) { }
- virtual CompLevel initial_compile_level() { return CompLevel_highest_tier; }
- virtual int compiler_count(CompLevel comp_level);
- virtual void do_safepoint_work();
- virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
- virtual void delay_compilation(Method* method);
- virtual void disable_compilation(Method* method);
- virtual bool is_mature(Method* method);
- virtual void initialize();
- virtual CompileTask* select_task(CompileQueue* compile_queue);
- virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
-};
-
-
-#endif // SHARE_RUNTIME_COMPILATIONPOLICY_HPP
--- a/src/hotspot/share/runtime/deoptimization.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/deoptimization.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -31,6 +31,7 @@
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/oopMapCache.hpp"
@@ -48,7 +49,6 @@
#include "oops/verifyOopClosure.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
--- a/src/hotspot/share/runtime/globals.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/globals.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -1197,9 +1197,6 @@
develop(bool, TraceCreateZombies, false, \
"trace creation of zombie nmethods") \
\
- notproduct(bool, IgnoreLockingAssertions, false, \
- "disable locking assertions (for speed)") \
- \
product(bool, RangeCheckElimination, true, \
"Eliminate range checks") \
\
--- a/src/hotspot/share/runtime/interfaceSupport.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/interfaceSupport.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -55,12 +55,6 @@
if (WalkStackALot) {
InterfaceSupport::walk_stack();
}
-#ifdef COMPILER2
- // This option is not used by Compiler 1
- if (StressDerivedPointers) {
- InterfaceSupport::stress_derived_pointers();
- }
-#endif
if (DeoptimizeALot || DeoptimizeRandom) {
InterfaceSupport::deoptimizeAll();
}
@@ -234,31 +228,6 @@
}
-void InterfaceSupport::stress_derived_pointers() {
-#ifdef COMPILER2
- JavaThread *thread = JavaThread::current();
- if (!is_init_completed()) return;
- ResourceMark rm(thread);
- bool found = false;
- for (StackFrameStream sfs(thread); !sfs.is_done() && !found; sfs.next()) {
- CodeBlob* cb = sfs.current()->cb();
- if (cb != NULL && cb->oop_maps() ) {
- // Find oopmap for current method
- const ImmutableOopMap* map = cb->oop_map_for_return_address(sfs.current()->pc());
- assert(map != NULL, "no oopmap found for pc");
- found = map->has_derived_pointer();
- }
- }
- if (found) {
- // $$$ Not sure what to do here.
- /*
- Scavenge::invoke(0);
- */
- }
-#endif
-}
-
-
void InterfaceSupport::verify_stack() {
JavaThread* thread = JavaThread::current();
ResourceMark rm(thread);
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -62,7 +62,6 @@
static void zombieAll();
static void deoptimizeAll();
- static void stress_derived_pointers();
static void verify_stack();
static void verify_last_frame();
# endif
--- a/src/hotspot/share/runtime/java.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/java.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -56,7 +56,6 @@
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/flags/flagSetting.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/runtime/javaCalls.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/javaCalls.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -26,6 +26,7 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/nmethod.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/linkResolver.hpp"
@@ -33,7 +34,6 @@
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jniCheck.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/runtime/mutexLocker.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -161,7 +161,6 @@
#ifdef ASSERT
void assert_locked_or_safepoint(const Mutex* lock) {
// check if this thread owns the lock (common case)
- if (IgnoreLockingAssertions) return;
assert(lock != NULL, "Need non-NULL lock");
if (lock->owned_by_self()) return;
if (SafepointSynchronize::is_at_safepoint()) return;
@@ -174,7 +173,6 @@
// a weaker assertion than the above
void assert_locked_or_safepoint_weak(const Mutex* lock) {
- if (IgnoreLockingAssertions) return;
assert(lock != NULL, "Need non-NULL lock");
if (lock->is_locked()) return;
if (SafepointSynchronize::is_at_safepoint()) return;
@@ -184,7 +182,6 @@
// a stronger assertion than the above
void assert_lock_strong(const Mutex* lock) {
- if (IgnoreLockingAssertions) return;
assert(lock != NULL, "Need non-NULL lock");
if (lock->owned_by_self()) return;
fatal("must own lock %s", lock->name());
--- a/src/hotspot/share/runtime/safepoint.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/safepoint.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -33,6 +33,7 @@
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
+#include "compiler/compilationPolicy.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/gcLocker.hpp"
#include "gc/shared/oopStorage.hpp"
@@ -47,7 +48,6 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -57,7 +57,6 @@
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
--- a/src/hotspot/share/runtime/sweeper.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/sweeper.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -38,7 +38,6 @@
#include "memory/universe.hpp"
#include "oops/method.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/compilationPolicy.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/handshake.hpp"
#include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/runtime/threadSMR.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/runtime/threadSMR.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -528,6 +528,22 @@
return;
}
+ if ( _thread == VM_Exit::shutdown_thread()) {
+ // The shutdown thread has removed itself from the Threads
+ // list and is safe to have a waiver from this check because
+ // VM_Exit::_shutdown_thread is not set until after the VMThread
+ // has started the final safepoint which holds the Threads_lock
+ // for the remainder of the VM's life.
+ return;
+ }
+
+ if (VMError::is_error_reported() &&
+ VMError::get_first_error_tid() == os::current_thread_id()) {
+ // If there is an error reported by this thread it may use ThreadsList even
+ // if it's unsafe.
+ return;
+ }
+
// The closure will attempt to verify that the calling thread can
// be found by threads_do() on the specified ThreadsList. If it
// is successful, then the specified ThreadsList was acquired as
@@ -540,12 +556,6 @@
// ThreadsList is not a stable hazard ptr and can be freed by
// another thread from the to-be-deleted list at any time.
//
- // Note: The shutdown thread has removed itself from the Threads
- // list and is safe to have a waiver from this check because
- // VM_Exit::_shutdown_thread is not set until after the VMThread
- // has started the final safepoint which holds the Threads_lock
- // for the remainder of the VM's life.
- //
VerifyHazardPtrThreadClosure cl(_thread);
ThreadsSMRSupport::threads_do(&cl, _list);
@@ -555,7 +565,7 @@
// In either case, we won't get past this point with a badly placed
// ThreadsListHandle.
- assert(cl.found() || _thread == VM_Exit::shutdown_thread(), "Acquired a ThreadsList snapshot from a thread not recognized by the Thread-SMR protocol.");
+ assert(cl.found(), "Acquired a ThreadsList snapshot from a thread not recognized by the Thread-SMR protocol.");
#endif
}
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1005 +0,0 @@
-/*
- * 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
- * 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 "compiler/compileBroker.hpp"
-#include "compiler/compilerOracle.hpp"
-#include "memory/resourceArea.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/safepoint.hpp"
-#include "runtime/safepointVerifiers.hpp"
-#include "runtime/tieredThresholdPolicy.hpp"
-#include "code/scopeDesc.hpp"
-#include "oops/method.inline.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci.hpp"
-#endif
-
-#ifdef TIERED
-
-#include "c1/c1_Compiler.hpp"
-#include "opto/c2compiler.hpp"
-
-template<CompLevel level>
-bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
- double threshold_scaling;
- if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
- scale *= threshold_scaling;
- }
- switch(level) {
- case CompLevel_aot:
- return (i >= Tier3AOTInvocationThreshold * scale) ||
- (i >= Tier3AOTMinInvocationThreshold * scale && i + b >= Tier3AOTCompileThreshold * scale);
- case CompLevel_none:
- case CompLevel_limited_profile:
- return (i >= Tier3InvocationThreshold * scale) ||
- (i >= Tier3MinInvocationThreshold * scale && i + b >= Tier3CompileThreshold * scale);
- case CompLevel_full_profile:
- return (i >= Tier4InvocationThreshold * scale) ||
- (i >= Tier4MinInvocationThreshold * scale && i + b >= Tier4CompileThreshold * scale);
- }
- return true;
-}
-
-template<CompLevel level>
-bool TieredThresholdPolicy::loop_predicate_helper(int i, int b, double scale, Method* method) {
- double threshold_scaling;
- if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
- scale *= threshold_scaling;
- }
- switch(level) {
- case CompLevel_aot:
- return b >= Tier3AOTBackEdgeThreshold * scale;
- case CompLevel_none:
- case CompLevel_limited_profile:
- return b >= Tier3BackEdgeThreshold * scale;
- case CompLevel_full_profile:
- return b >= Tier4BackEdgeThreshold * scale;
- }
- return true;
-}
-
-// Simple methods are as good being compiled with C1 as C2.
-// Determine if a given method is such a case.
-bool TieredThresholdPolicy::is_trivial(Method* method) {
- if (method->is_accessor() ||
- method->is_constant_getter()) {
- return true;
- }
- return false;
-}
-
-bool TieredThresholdPolicy::should_compile_at_level_simple(Method* method) {
- if (TieredThresholdPolicy::is_trivial(method)) {
- return true;
- }
-#if INCLUDE_JVMCI
- if (UseJVMCICompiler) {
- AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization);
- if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) {
- return true;
- }
- }
-#endif
- return false;
-}
-
-CompLevel TieredThresholdPolicy::comp_level(Method* method) {
- CompiledMethod *nm = method->code();
- if (nm != NULL && nm->is_in_use()) {
- return (CompLevel)nm->comp_level();
- }
- return CompLevel_none;
-}
-
-void TieredThresholdPolicy::print_counters(const char* prefix, const methodHandle& mh) {
- int invocation_count = mh->invocation_count();
- int backedge_count = mh->backedge_count();
- MethodData* mdh = mh->method_data();
- int mdo_invocations = 0, mdo_backedges = 0;
- int mdo_invocations_start = 0, mdo_backedges_start = 0;
- if (mdh != NULL) {
- mdo_invocations = mdh->invocation_count();
- mdo_backedges = mdh->backedge_count();
- mdo_invocations_start = mdh->invocation_count_start();
- mdo_backedges_start = mdh->backedge_count_start();
- }
- tty->print(" %stotal=%d,%d %smdo=%d(%d),%d(%d)", prefix,
- invocation_count, backedge_count, prefix,
- mdo_invocations, mdo_invocations_start,
- mdo_backedges, mdo_backedges_start);
- tty->print(" %smax levels=%d,%d", prefix,
- mh->highest_comp_level(), mh->highest_osr_comp_level());
-}
-
-// Print an event.
-void TieredThresholdPolicy::print_event(EventType type, const methodHandle& mh, const methodHandle& imh,
- int bci, CompLevel level) {
- bool inlinee_event = mh() != imh();
-
- ttyLocker tty_lock;
- tty->print("%lf: [", os::elapsedTime());
-
- switch(type) {
- case CALL:
- tty->print("call");
- break;
- case LOOP:
- tty->print("loop");
- break;
- case COMPILE:
- tty->print("compile");
- break;
- case REMOVE_FROM_QUEUE:
- tty->print("remove-from-queue");
- break;
- case UPDATE_IN_QUEUE:
- tty->print("update-in-queue");
- break;
- case REPROFILE:
- tty->print("reprofile");
- break;
- case MAKE_NOT_ENTRANT:
- tty->print("make-not-entrant");
- break;
- default:
- tty->print("unknown");
- }
-
- tty->print(" level=%d ", level);
-
- ResourceMark rm;
- char *method_name = mh->name_and_sig_as_C_string();
- tty->print("[%s", method_name);
- if (inlinee_event) {
- char *inlinee_name = imh->name_and_sig_as_C_string();
- tty->print(" [%s]] ", inlinee_name);
- }
- else tty->print("] ");
- tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
- CompileBroker::queue_size(CompLevel_full_optimization));
-
- print_specific(type, mh, imh, bci, level);
-
- if (type != COMPILE) {
- print_counters("", mh);
- if (inlinee_event) {
- print_counters("inlinee ", imh);
- }
- tty->print(" compilable=");
- bool need_comma = false;
- if (!mh->is_not_compilable(CompLevel_full_profile)) {
- tty->print("c1");
- need_comma = true;
- }
- if (!mh->is_not_osr_compilable(CompLevel_full_profile)) {
- if (need_comma) tty->print(",");
- tty->print("c1-osr");
- need_comma = true;
- }
- if (!mh->is_not_compilable(CompLevel_full_optimization)) {
- if (need_comma) tty->print(",");
- tty->print("c2");
- need_comma = true;
- }
- if (!mh->is_not_osr_compilable(CompLevel_full_optimization)) {
- if (need_comma) tty->print(",");
- tty->print("c2-osr");
- }
- tty->print(" status=");
- if (mh->queued_for_compilation()) {
- tty->print("in-queue");
- } else tty->print("idle");
- }
- tty->print_cr("]");
-}
-
-void TieredThresholdPolicy::initialize() {
- int count = CICompilerCount;
- bool c1_only = TieredStopAtLevel < CompLevel_full_optimization;
-#ifdef _LP64
- // Turn on ergonomic compiler count selection
- if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
- FLAG_SET_DEFAULT(CICompilerCountPerCPU, true);
- }
- if (CICompilerCountPerCPU) {
- // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
- int log_cpu = log2_int(os::active_processor_count());
- int loglog_cpu = log2_int(MAX2(log_cpu, 1));
- count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
- // Make sure there is enough space in the code cache to hold all the compiler buffers
- size_t c1_size = Compiler::code_buffer_size();
- size_t c2_size = C2Compiler::initial_code_buffer_size();
- size_t buffer_size = c1_only ? c1_size : (c1_size/3 + 2*c2_size/3);
- int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size;
- if (count > max_count) {
- // Lower the compiler count such that all buffers fit into the code cache
- count = MAX2(max_count, c1_only ? 1 : 2);
- }
- FLAG_SET_ERGO(CICompilerCount, count);
- }
-#else
- // On 32-bit systems, the number of compiler threads is limited to 3.
- // On these systems, the virtual address space available to the JVM
- // is usually limited to 2-4 GB (the exact value depends on the platform).
- // As the compilers (especially C2) can consume a large amount of
- // memory, scaling the number of compiler threads with the number of
- // available cores can result in the exhaustion of the address space
- /// available to the VM and thus cause the VM to crash.
- if (FLAG_IS_DEFAULT(CICompilerCount)) {
- count = 3;
- FLAG_SET_ERGO(CICompilerCount, count);
- }
-#endif
-
- if (c1_only) {
- // No C2 compiler thread required
- set_c1_count(count);
- } else {
- set_c1_count(MAX2(count / 3, 1));
- set_c2_count(MAX2(count - c1_count(), 1));
- }
- assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
-
- // Some inlining tuning
-#ifdef X86
- if (FLAG_IS_DEFAULT(InlineSmallCode)) {
- FLAG_SET_DEFAULT(InlineSmallCode, 2000);
- }
-#endif
-
-#if defined SPARC || defined AARCH64
- if (FLAG_IS_DEFAULT(InlineSmallCode)) {
- FLAG_SET_DEFAULT(InlineSmallCode, 2500);
- }
-#endif
-
- set_increase_threshold_at_ratio();
- set_start_time(os::javaTimeMillis());
-}
-
-void TieredThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
- if (!counter->carry() && counter->count() > InvocationCounter::count_limit / 2) {
- counter->set_carry_flag();
- }
-}
-
-// Set carry flags on the counters if necessary
-void TieredThresholdPolicy::handle_counter_overflow(Method* method) {
- MethodCounters *mcs = method->method_counters();
- if (mcs != NULL) {
- set_carry_if_necessary(mcs->invocation_counter());
- set_carry_if_necessary(mcs->backedge_counter());
- }
- MethodData* mdo = method->method_data();
- if (mdo != NULL) {
- set_carry_if_necessary(mdo->invocation_counter());
- set_carry_if_necessary(mdo->backedge_counter());
- }
-}
-
-// Called with the queue locked and with at least one element
-CompileTask* TieredThresholdPolicy::select_task(CompileQueue* compile_queue) {
- CompileTask *max_blocking_task = NULL;
- CompileTask *max_task = NULL;
- Method* max_method = NULL;
- jlong t = os::javaTimeMillis();
- // Iterate through the queue and find a method with a maximum rate.
- for (CompileTask* task = compile_queue->first(); task != NULL;) {
- CompileTask* next_task = task->next();
- Method* method = task->method();
- // If a method was unloaded or has been stale for some time, remove it from the queue.
- // Blocking tasks and tasks submitted from whitebox API don't become stale
- if (task->is_unloaded() || (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method))) {
- if (!task->is_unloaded()) {
- if (PrintTieredEvents) {
- print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel) task->comp_level());
- }
- method->clear_queued_for_compilation();
- }
- compile_queue->remove_and_mark_stale(task);
- task = next_task;
- continue;
- }
- update_rate(t, method);
- if (max_task == NULL || compare_methods(method, max_method)) {
- // Select a method with the highest rate
- max_task = task;
- max_method = method;
- }
-
- if (task->is_blocking()) {
- if (max_blocking_task == NULL || compare_methods(method, max_blocking_task->method())) {
- max_blocking_task = task;
- }
- }
-
- task = next_task;
- }
-
- if (max_blocking_task != NULL) {
- // In blocking compilation mode, the CompileBroker will make
- // compilations submitted by a JVMCI compiler thread non-blocking. These
- // compilations should be scheduled after all blocking compilations
- // to service non-compiler related compilations sooner and reduce the
- // chance of such compilations timing out.
- max_task = max_blocking_task;
- max_method = max_task->method();
- }
-
- if (max_task != NULL && max_task->comp_level() == CompLevel_full_profile &&
- TieredStopAtLevel > CompLevel_full_profile &&
- max_method != NULL && is_method_profiled(max_method)) {
- max_task->set_comp_level(CompLevel_limited_profile);
-
- if (CompileBroker::compilation_is_complete(max_method, max_task->osr_bci(), CompLevel_limited_profile)) {
- if (PrintTieredEvents) {
- print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
- }
- compile_queue->remove_and_mark_stale(max_task);
- max_method->clear_queued_for_compilation();
- return NULL;
- }
-
- if (PrintTieredEvents) {
- print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
- }
- }
-
- return max_task;
-}
-
-void TieredThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
- for (ScopeDesc* sd = trap_scope;; sd = sd->sender()) {
- if (PrintTieredEvents) {
- methodHandle mh(sd->method());
- print_event(REPROFILE, mh, mh, InvocationEntryBci, CompLevel_none);
- }
- MethodData* mdo = sd->method()->method_data();
- if (mdo != NULL) {
- mdo->reset_start_counters();
- }
- if (sd->is_top()) break;
- }
-}
-
-nmethod* TieredThresholdPolicy::event(const methodHandle& method, const methodHandle& inlinee,
- int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
- if (comp_level == CompLevel_none &&
- JvmtiExport::can_post_interpreter_events() &&
- thread->is_interp_only_mode()) {
- return NULL;
- }
- if (ReplayCompiles) {
- // Don't trigger other compiles in testing mode
- return NULL;
- }
-
- handle_counter_overflow(method());
- if (method() != inlinee()) {
- handle_counter_overflow(inlinee());
- }
-
- if (PrintTieredEvents) {
- print_event(bci == InvocationEntryBci ? CALL : LOOP, method, inlinee, bci, comp_level);
- }
-
- if (bci == InvocationEntryBci) {
- method_invocation_event(method, inlinee, comp_level, nm, thread);
- } else {
- // method == inlinee if the event originated in the main method
- method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
- // Check if event led to a higher level OSR compilation
- CompLevel expected_comp_level = comp_level;
- if (inlinee->is_not_osr_compilable(expected_comp_level)) {
- // It's not possble to reach the expected level so fall back to simple.
- expected_comp_level = CompLevel_simple;
- }
- nmethod* osr_nm = inlinee->lookup_osr_nmethod_for(bci, expected_comp_level, false);
- assert(osr_nm == NULL || osr_nm->comp_level() >= expected_comp_level, "lookup_osr_nmethod_for is broken");
- if (osr_nm != NULL) {
- // Perform OSR with new nmethod
- return osr_nm;
- }
- }
- return NULL;
-}
-
-// Check if the method can be compiled, change level if necessary
-void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
- assert(level <= TieredStopAtLevel, "Invalid compilation level");
- if (level == CompLevel_none) {
- return;
- }
- if (level == CompLevel_aot) {
- if (mh->has_aot_code()) {
- if (PrintTieredEvents) {
- print_event(COMPILE, mh, mh, bci, level);
- }
- MutexLocker ml(Compile_lock);
- NoSafepointVerifier nsv;
- if (mh->has_aot_code() && mh->code() != mh->aot_code()) {
- mh->aot_code()->make_entrant();
- if (mh->has_compiled_code()) {
- mh->code()->make_not_entrant();
- }
- MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
- Method::set_code(mh, mh->aot_code());
- }
- }
- return;
- }
-
- // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling
- // in the interpreter and then compile with C2 (the transition function will request that,
- // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with
- // pure C1.
- if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) {
- if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) {
- compile(mh, bci, CompLevel_simple, thread);
- }
- return;
- }
- if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) {
- if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) {
- nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false);
- if (osr_nm != NULL && osr_nm->comp_level() > CompLevel_simple) {
- // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted.
- osr_nm->make_not_entrant();
- }
- compile(mh, bci, CompLevel_simple, thread);
- }
- return;
- }
- if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) {
- return;
- }
- if (!CompileBroker::compilation_is_in_queue(mh)) {
- if (PrintTieredEvents) {
- print_event(COMPILE, mh, mh, bci, level);
- }
- submit_compile(mh, bci, level, thread);
- }
-}
-
-// Update the rate and submit compile
-void TieredThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
- int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
- update_rate(os::javaTimeMillis(), mh());
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
-}
-
-// Print an event.
-void TieredThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh,
- int bci, CompLevel level) {
- tty->print(" rate=");
- if (mh->prev_time() == 0) tty->print("n/a");
- else tty->print("%f", mh->rate());
-
- tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
- threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
-
-}
-
-// update_rate() is called from select_task() while holding a compile queue lock.
-void TieredThresholdPolicy::update_rate(jlong t, Method* m) {
- // Skip update if counters are absent.
- // Can't allocate them since we are holding compile queue lock.
- if (m->method_counters() == NULL) return;
-
- if (is_old(m)) {
- // We don't remove old methods from the queue,
- // so we can just zero the rate.
- m->set_rate(0);
- return;
- }
-
- // We don't update the rate if we've just came out of a safepoint.
- // delta_s is the time since last safepoint in milliseconds.
- jlong delta_s = t - SafepointTracing::end_of_last_safepoint_epoch_ms();
- jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement
- // How many events were there since the last time?
- int event_count = m->invocation_count() + m->backedge_count();
- int delta_e = event_count - m->prev_event_count();
-
- // We should be running for at least 1ms.
- if (delta_s >= TieredRateUpdateMinTime) {
- // And we must've taken the previous point at least 1ms before.
- if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
- m->set_prev_time(t);
- m->set_prev_event_count(event_count);
- m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
- } else {
- if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
- // If nothing happened for 25ms, zero the rate. Don't modify prev values.
- m->set_rate(0);
- }
- }
- }
-}
-
-// Check if this method has been stale for a given number of milliseconds.
-// See select_task().
-bool TieredThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) {
- jlong delta_s = t - SafepointTracing::end_of_last_safepoint_epoch_ms();
- jlong delta_t = t - m->prev_time();
- if (delta_t > timeout && delta_s > timeout) {
- int event_count = m->invocation_count() + m->backedge_count();
- int delta_e = event_count - m->prev_event_count();
- // Return true if there were no events.
- return delta_e == 0;
- }
- return false;
-}
-
-// We don't remove old methods from the compile queue even if they have
-// very low activity. See select_task().
-bool TieredThresholdPolicy::is_old(Method* method) {
- return method->invocation_count() > 50000 || method->backedge_count() > 500000;
-}
-
-double TieredThresholdPolicy::weight(Method* method) {
- return (double)(method->rate() + 1) *
- (method->invocation_count() + 1) * (method->backedge_count() + 1);
-}
-
-// Apply heuristics and return true if x should be compiled before y
-bool TieredThresholdPolicy::compare_methods(Method* x, Method* y) {
- if (x->highest_comp_level() > y->highest_comp_level()) {
- // recompilation after deopt
- return true;
- } else
- if (x->highest_comp_level() == y->highest_comp_level()) {
- if (weight(x) > weight(y)) {
- return true;
- }
- }
- return false;
-}
-
-// Is method profiled enough?
-bool TieredThresholdPolicy::is_method_profiled(Method* method) {
- MethodData* mdo = method->method_data();
- if (mdo != NULL) {
- int i = mdo->invocation_count_delta();
- int b = mdo->backedge_count_delta();
- return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
- }
- return false;
-}
-
-double TieredThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
- double queue_size = CompileBroker::queue_size(level);
- int comp_count = compiler_count(level);
- double k = queue_size / (feedback_k * comp_count) + 1;
-
- // Increase C1 compile threshold when the code cache is filled more
- // than specified by IncreaseFirstTierCompileThresholdAt percentage.
- // The main intention is to keep enough free space for C2 compiled code
- // to achieve peak performance if the code cache is under stress.
- if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization)) {
- double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level));
- if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
- k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
- }
- }
- return k;
-}
-
-// Call and loop predicates determine whether a transition to a higher
-// compilation level should be performed (pointers to predicate functions
-// are passed to common()).
-// Tier?LoadFeedback is basically a coefficient that determines of
-// how many methods per compiler thread can be in the queue before
-// the threshold values double.
-bool TieredThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
- switch(cur_level) {
- case CompLevel_aot: {
- double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
- return loop_predicate_helper<CompLevel_aot>(i, b, k, method);
- }
- case CompLevel_none:
- case CompLevel_limited_profile: {
- double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
- return loop_predicate_helper<CompLevel_none>(i, b, k, method);
- }
- case CompLevel_full_profile: {
- double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
- return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
- }
- default:
- return true;
- }
-}
-
-bool TieredThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
- switch(cur_level) {
- case CompLevel_aot: {
- double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
- return call_predicate_helper<CompLevel_aot>(i, b, k, method);
- }
- case CompLevel_none:
- case CompLevel_limited_profile: {
- double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
- return call_predicate_helper<CompLevel_none>(i, b, k, method);
- }
- case CompLevel_full_profile: {
- double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
- return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
- }
- default:
- return true;
- }
-}
-
-// Determine is a method is mature.
-bool TieredThresholdPolicy::is_mature(Method* method) {
- if (should_compile_at_level_simple(method)) return true;
- MethodData* mdo = method->method_data();
- if (mdo != NULL) {
- int i = mdo->invocation_count();
- int b = mdo->backedge_count();
- double k = ProfileMaturityPercentage / 100.0;
- return call_predicate_helper<CompLevel_full_profile>(i, b, k, method) ||
- loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
- }
- return false;
-}
-
-// If a method is old enough and is still in the interpreter we would want to
-// start profiling without waiting for the compiled method to arrive.
-// We also take the load on compilers into the account.
-bool TieredThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) {
- if (cur_level == CompLevel_none &&
- CompileBroker::queue_size(CompLevel_full_optimization) <=
- Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
- int i = method->invocation_count();
- int b = method->backedge_count();
- double k = Tier0ProfilingStartPercentage / 100.0;
- return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
- }
- return false;
-}
-
-// Inlining control: if we're compiling a profiled method with C1 and the callee
-// is known to have OSRed in a C2 version, don't inline it.
-bool TieredThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) {
- CompLevel comp_level = (CompLevel)env->comp_level();
- if (comp_level == CompLevel_full_profile ||
- comp_level == CompLevel_limited_profile) {
- return callee->highest_osr_comp_level() == CompLevel_full_optimization;
- }
- return false;
-}
-
-// Create MDO if necessary.
-void TieredThresholdPolicy::create_mdo(const methodHandle& mh, JavaThread* THREAD) {
- if (mh->is_native() ||
- mh->is_abstract() ||
- mh->is_accessor() ||
- mh->is_constant_getter()) {
- return;
- }
- if (mh->method_data() == NULL) {
- Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
- }
-}
-
-
-/*
- * Method states:
- * 0 - interpreter (CompLevel_none)
- * 1 - pure C1 (CompLevel_simple)
- * 2 - C1 with invocation and backedge counting (CompLevel_limited_profile)
- * 3 - C1 with full profiling (CompLevel_full_profile)
- * 4 - C2 (CompLevel_full_optimization)
- *
- * Common state transition patterns:
- * a. 0 -> 3 -> 4.
- * The most common path. But note that even in this straightforward case
- * profiling can start at level 0 and finish at level 3.
- *
- * b. 0 -> 2 -> 3 -> 4.
- * This case occurs when the load on C2 is deemed too high. So, instead of transitioning
- * into state 3 directly and over-profiling while a method is in the C2 queue we transition to
- * level 2 and wait until the load on C2 decreases. This path is disabled for OSRs.
- *
- * c. 0 -> (3->2) -> 4.
- * In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
- * to enable the profiling to fully occur at level 0. In this case we change the compilation level
- * of the method to 2 while the request is still in-queue, because it'll allow it to run much faster
- * without full profiling while c2 is compiling.
- *
- * d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
- * After a method was once compiled with C1 it can be identified as trivial and be compiled to
- * level 1. These transition can also occur if a method can't be compiled with C2 but can with C1.
- *
- * e. 0 -> 4.
- * This can happen if a method fails C1 compilation (it will still be profiled in the interpreter)
- * or because of a deopt that didn't require reprofiling (compilation won't happen in this case because
- * the compiled version already exists).
- *
- * Note that since state 0 can be reached from any other state via deoptimization different loops
- * are possible.
- *
- */
-
-// Common transition function. Given a predicate determines if a method should transition to another level.
-CompLevel TieredThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback) {
- CompLevel next_level = cur_level;
- int i = method->invocation_count();
- int b = method->backedge_count();
-
- if (should_compile_at_level_simple(method)) {
- next_level = CompLevel_simple;
- } else {
- switch(cur_level) {
- default: break;
- case CompLevel_aot: {
- // If we were at full profile level, would we switch to full opt?
- if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
- next_level = CompLevel_full_optimization;
- } else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
- Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
- (this->*p)(i, b, cur_level, method))) {
- next_level = CompLevel_full_profile;
- }
- }
- break;
- case CompLevel_none:
- // If we were at full profile level, would we switch to full opt?
- if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
- next_level = CompLevel_full_optimization;
- } else if ((this->*p)(i, b, cur_level, method)) {
-#if INCLUDE_JVMCI
- if (EnableJVMCI && UseJVMCICompiler) {
- // Since JVMCI takes a while to warm up, its queue inevitably backs up during
- // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root
- // compilation method and all potential inlinees have mature profiles (which
- // includes type profiling). If it sees immature profiles, JVMCI's inliner
- // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to
- // exploring/inlining too many graphs). Since a rewrite of the inliner is
- // in progress, we simply disable the dialing back heuristic for now and will
- // revisit this decision once the new inliner is completed.
- next_level = CompLevel_full_profile;
- } else
-#endif
- {
- // C1-generated fully profiled code is about 30% slower than the limited profile
- // code that has only invocation and backedge counters. The observation is that
- // if C2 queue is large enough we can spend too much time in the fully profiled code
- // while waiting for C2 to pick the method from the queue. To alleviate this problem
- // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
- // we choose to compile a limited profiled version and then recompile with full profiling
- // when the load on C2 goes down.
- if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
- Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
- next_level = CompLevel_limited_profile;
- } else {
- next_level = CompLevel_full_profile;
- }
- }
- }
- break;
- case CompLevel_limited_profile:
- if (is_method_profiled(method)) {
- // Special case: we got here because this method was fully profiled in the interpreter.
- next_level = CompLevel_full_optimization;
- } else {
- MethodData* mdo = method->method_data();
- if (mdo != NULL) {
- if (mdo->would_profile()) {
- if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
- Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
- (this->*p)(i, b, cur_level, method))) {
- next_level = CompLevel_full_profile;
- }
- } else {
- next_level = CompLevel_full_optimization;
- }
- } else {
- // If there is no MDO we need to profile
- if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
- Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
- (this->*p)(i, b, cur_level, method))) {
- next_level = CompLevel_full_profile;
- }
- }
- }
- break;
- case CompLevel_full_profile:
- {
- MethodData* mdo = method->method_data();
- if (mdo != NULL) {
- if (mdo->would_profile()) {
- int mdo_i = mdo->invocation_count_delta();
- int mdo_b = mdo->backedge_count_delta();
- if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
- next_level = CompLevel_full_optimization;
- }
- } else {
- next_level = CompLevel_full_optimization;
- }
- }
- }
- break;
- }
- }
- return MIN2(next_level, (CompLevel)TieredStopAtLevel);
-}
-
-// Determine if a method should be compiled with a normal entry point at a different level.
-CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) {
- CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
- common(&TieredThresholdPolicy::loop_predicate, method, cur_level, true));
- CompLevel next_level = common(&TieredThresholdPolicy::call_predicate, method, cur_level);
-
- // If OSR method level is greater than the regular method level, the levels should be
- // equalized by raising the regular method level in order to avoid OSRs during each
- // invocation of the method.
- if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) {
- MethodData* mdo = method->method_data();
- guarantee(mdo != NULL, "MDO should not be NULL");
- if (mdo->invocation_count() >= 1) {
- next_level = CompLevel_full_optimization;
- }
- } else {
- next_level = MAX2(osr_level, next_level);
- }
- return next_level;
-}
-
-// Determine if we should do an OSR compilation of a given method.
-CompLevel TieredThresholdPolicy::loop_event(Method* method, CompLevel cur_level, JavaThread* thread) {
- CompLevel next_level = common(&TieredThresholdPolicy::loop_predicate, method, cur_level, true);
- if (cur_level == CompLevel_none) {
- // If there is a live OSR method that means that we deopted to the interpreter
- // for the transition.
- CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level);
- if (osr_level > CompLevel_none) {
- return osr_level;
- }
- }
- return next_level;
-}
-
-bool TieredThresholdPolicy::maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread) {
- if (UseAOT) {
- if (cur_level == CompLevel_full_profile || cur_level == CompLevel_none) {
- // If the current level is full profile or interpreter and we're switching to any other level,
- // activate the AOT code back first so that we won't waste time overprofiling.
- compile(mh, InvocationEntryBci, CompLevel_aot, thread);
- // Fall through for JIT compilation.
- }
- if (next_level == CompLevel_limited_profile && cur_level != CompLevel_aot && mh->has_aot_code()) {
- // If the next level is limited profile, use the aot code (if there is any),
- // since it's essentially the same thing.
- compile(mh, InvocationEntryBci, CompLevel_aot, thread);
- // Not need to JIT, we're done.
- return true;
- }
- }
- return false;
-}
-
-
-// Handle the invocation event.
-void TieredThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
- CompLevel level, CompiledMethod* nm, JavaThread* thread) {
- if (should_create_mdo(mh(), level)) {
- create_mdo(mh, thread);
- }
- CompLevel next_level = call_event(mh(), level, thread);
- if (next_level != level) {
- if (maybe_switch_to_aot(mh, level, next_level, thread)) {
- // No JITting necessary
- return;
- }
- if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
- compile(mh, InvocationEntryBci, next_level, thread);
- }
- }
-}
-
-// Handle the back branch event. Notice that we can compile the method
-// with a regular entry from here.
-void TieredThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
- int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
- if (should_create_mdo(mh(), level)) {
- create_mdo(mh, thread);
- }
- // Check if MDO should be created for the inlined method
- if (should_create_mdo(imh(), level)) {
- create_mdo(imh, thread);
- }
-
- if (is_compilation_enabled()) {
- CompLevel next_osr_level = loop_event(imh(), level, thread);
- CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
- // At the very least compile the OSR version
- if (!CompileBroker::compilation_is_in_queue(imh) && (next_osr_level != level)) {
- compile(imh, bci, next_osr_level, thread);
- }
-
- // Use loop event as an opportunity to also check if there's been
- // enough calls.
- CompLevel cur_level, next_level;
- if (mh() != imh()) { // If there is an enclosing method
- if (level == CompLevel_aot) {
- // Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
- if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
- compile(mh, InvocationEntryBci, MIN2((CompLevel)TieredStopAtLevel, CompLevel_full_profile), thread);
- }
- } else {
- // Current loop event level is not AOT
- guarantee(nm != NULL, "Should have nmethod here");
- cur_level = comp_level(mh());
- next_level = call_event(mh(), cur_level, thread);
-
- if (max_osr_level == CompLevel_full_optimization) {
- // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts
- bool make_not_entrant = false;
- if (nm->is_osr_method()) {
- // This is an osr method, just make it not entrant and recompile later if needed
- make_not_entrant = true;
- } else {
- if (next_level != CompLevel_full_optimization) {
- // next_level is not full opt, so we need to recompile the
- // enclosing method without the inlinee
- cur_level = CompLevel_none;
- make_not_entrant = true;
- }
- }
- if (make_not_entrant) {
- if (PrintTieredEvents) {
- int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci;
- print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level);
- }
- nm->make_not_entrant();
- }
- }
- // Fix up next_level if necessary to avoid deopts
- if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) {
- next_level = CompLevel_full_profile;
- }
- if (cur_level != next_level) {
- if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
- compile(mh, InvocationEntryBci, next_level, thread);
- }
- }
- }
- } else {
- cur_level = comp_level(mh());
- next_level = call_event(mh(), cur_level, thread);
- if (next_level != cur_level) {
- if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
- compile(mh, InvocationEntryBci, next_level, thread);
- }
- }
- }
- }
-}
-
-#endif
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.hpp Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * 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
- * 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_RUNTIME_TIEREDTHRESHOLDPOLICY_HPP
-#define SHARE_RUNTIME_TIEREDTHRESHOLDPOLICY_HPP
-
-#include "code/nmethod.hpp"
-#include "oops/methodData.hpp"
-#include "runtime/compilationPolicy.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-#ifdef TIERED
-
-class CompileTask;
-class CompileQueue;
-/*
- * The system supports 5 execution levels:
- * * level 0 - interpreter
- * * level 1 - C1 with full optimization (no profiling)
- * * level 2 - C1 with invocation and backedge counters
- * * level 3 - C1 with full profiling (level 2 + MDO)
- * * level 4 - C2
- *
- * Levels 0, 2 and 3 periodically notify the runtime about the current value of the counters
- * (invocation counters and backedge counters). The frequency of these notifications is
- * different at each level. These notifications are used by the policy to decide what transition
- * to make.
- *
- * Execution starts at level 0 (interpreter), then the policy can decide either to compile the
- * method at level 3 or level 2. The decision is based on the following factors:
- * 1. The length of the C2 queue determines the next level. The observation is that level 2
- * is generally faster than level 3 by about 30%, therefore we would want to minimize the time
- * a method spends at level 3. We should only spend the time at level 3 that is necessary to get
- * adequate profiling. So, if the C2 queue is long enough it is more beneficial to go first to
- * level 2, because if we transitioned to level 3 we would be stuck there until our C2 compile
- * request makes its way through the long queue. When the load on C2 recedes we are going to
- * recompile at level 3 and start gathering profiling information.
- * 2. The length of C1 queue is used to dynamically adjust the thresholds, so as to introduce
- * additional filtering if the compiler is overloaded. The rationale is that by the time a
- * method gets compiled it can become unused, so it doesn't make sense to put too much onto the
- * queue.
- *
- * After profiling is completed at level 3 the transition is made to level 4. Again, the length
- * of the C2 queue is used as a feedback to adjust the thresholds.
- *
- * After the first C1 compile some basic information is determined about the code like the number
- * of the blocks and the number of the loops. Based on that it can be decided that a method
- * is trivial and compiling it with C1 will yield the same code. In this case the method is
- * compiled at level 1 instead of 4.
- *
- * We also support profiling at level 0. If C1 is slow enough to produce the level 3 version of
- * the code and the C2 queue is sufficiently small we can decide to start profiling in the
- * interpreter (and continue profiling in the compiled code once the level 3 version arrives).
- * If the profiling at level 0 is fully completed before level 3 version is produced, a level 2
- * version is compiled instead in order to run faster waiting for a level 4 version.
- *
- * Compile queues are implemented as priority queues - for each method in the queue we compute
- * the event rate (the number of invocation and backedge counter increments per unit of time).
- * When getting an element off the queue we pick the one with the largest rate. Maintaining the
- * rate also allows us to remove stale methods (the ones that got on the queue but stopped
- * being used shortly after that).
-*/
-
-/* Command line options:
- * - Tier?InvokeNotifyFreqLog and Tier?BackedgeNotifyFreqLog control the frequency of method
- * invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
- * makes a call into the runtime.
- *
- * - Tier?InvocationThreshold, Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
- * compilation thresholds.
- * Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
- * Other thresholds work as follows:
- *
- * Transition from interpreter (level 0) to C1 with full profiling (level 3) happens when
- * the following predicate is true (X is the level):
- *
- * i > TierXInvocationThreshold * s || (i > TierXMinInvocationThreshold * s && i + b > TierXCompileThreshold * s),
- *
- * where $i$ is the number of method invocations, $b$ number of backedges and $s$ is the scaling
- * coefficient that will be discussed further.
- * The intuition is to equalize the time that is spend profiling each method.
- * The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
- * noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
- * from Method* and for 3->4 transition they come from MDO (since profiled invocations are
- * counted separately). Finally, if a method does not contain anything worth profiling, a transition
- * from level 3 to level 4 occurs without considering thresholds (e.g., with fewer invocations than
- * what is specified by Tier4InvocationThreshold).
- *
- * OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
- *
- * - Tier?LoadFeedback options are used to automatically scale the predicates described above depending
- * on the compiler load. The scaling coefficients are computed as follows:
- *
- * s = queue_size_X / (TierXLoadFeedback * compiler_count_X) + 1,
- *
- * where queue_size_X is the current size of the compiler queue of level X, and compiler_count_X
- * is the number of level X compiler threads.
- *
- * Basically these parameters describe how many methods should be in the compile queue
- * per compiler thread before the scaling coefficient increases by one.
- *
- * This feedback provides the mechanism to automatically control the flow of compilation requests
- * depending on the machine speed, mutator load and other external factors.
- *
- * - Tier3DelayOn and Tier3DelayOff parameters control another important feedback loop.
- * Consider the following observation: a method compiled with full profiling (level 3)
- * is about 30% slower than a method at level 2 (just invocation and backedge counters, no MDO).
- * Normally, the following transitions will occur: 0->3->4. The problem arises when the C2 queue
- * gets congested and the 3->4 transition is delayed. While the method is the C2 queue it continues
- * executing at level 3 for much longer time than is required by the predicate and at suboptimal speed.
- * The idea is to dynamically change the behavior of the system in such a way that if a substantial
- * load on C2 is detected we would first do the 0->2 transition allowing a method to run faster.
- * And then when the load decreases to allow 2->3 transitions.
- *
- * Tier3Delay* parameters control this switching mechanism.
- * Tier3DelayOn is the number of methods in the C2 queue per compiler thread after which the policy
- * no longer does 0->3 transitions but does 0->2 transitions instead.
- * Tier3DelayOff switches the original behavior back when the number of methods in the C2 queue
- * per compiler thread falls below the specified amount.
- * The hysteresis is necessary to avoid jitter.
- *
- * - TieredCompileTaskTimeout is the amount of time an idle method can spend in the compile queue.
- * Basically, since we use the event rate d(i + b)/dt as a value of priority when selecting a method to
- * compile from the compile queue, we also can detect stale methods for which the rate has been
- * 0 for some time in the same iteration. Stale methods can appear in the queue when an application
- * abruptly changes its behavior.
- *
- * - TieredStopAtLevel, is used mostly for testing. It allows to bypass the policy logic and stick
- * to a given level. For example it's useful to set TieredStopAtLevel = 1 in order to compile everything
- * with pure c1.
- *
- * - Tier0ProfilingStartPercentage allows the interpreter to start profiling when the inequalities in the
- * 0->3 predicate are already exceeded by the given percentage but the level 3 version of the
- * method is still not ready. We can even go directly from level 0 to 4 if c1 doesn't produce a compiled
- * version in time. This reduces the overall transition to level 4 and decreases the startup time.
- * Note that this behavior is also guarded by the Tier3Delay mechanism: when the c2 queue is too long
- * these is not reason to start profiling prematurely.
- *
- * - TieredRateUpdateMinTime and TieredRateUpdateMaxTime are parameters of the rate computation.
- * Basically, the rate is not computed more frequently than TieredRateUpdateMinTime and is considered
- * to be zero if no events occurred in TieredRateUpdateMaxTime.
- */
-
-class TieredThresholdPolicy : public CompilationPolicy {
- jlong _start_time;
- int _c1_count, _c2_count;
-
- // Check if the counter is big enough and set carry (effectively infinity).
- inline void set_carry_if_necessary(InvocationCounter *counter);
- // Set carry flags in the counters (in Method* and MDO).
- inline void handle_counter_overflow(Method* method);
- // Call and loop predicates determine whether a transition to a higher compilation
- // level should be performed (pointers to predicate functions are passed to common_TF().
- // Predicates also take compiler load into account.
- typedef bool (TieredThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
- bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
- bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
- // Common transition function. Given a predicate determines if a method should transition to another level.
- CompLevel common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback = false);
- // Transition functions.
- // call_event determines if a method should be compiled at a different
- // level with a regular invocation entry.
- CompLevel call_event(Method* method, CompLevel cur_level, JavaThread* thread);
- // loop_event checks if a method should be OSR compiled at a different
- // level.
- CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread* thread);
- void print_counters(const char* prefix, const methodHandle& mh);
- // Has a method been long around?
- // We don't remove old methods from the compile queue even if they have
- // very low activity (see select_task()).
- inline bool is_old(Method* method);
- // Was a given method inactive for a given number of milliseconds.
- // If it is, we would remove it from the queue (see select_task()).
- inline bool is_stale(jlong t, jlong timeout, Method* m);
- // Compute the weight of the method for the compilation scheduling
- inline double weight(Method* method);
- // Apply heuristics and return true if x should be compiled before y
- inline bool compare_methods(Method* x, Method* y);
- // Compute event rate for a given method. The rate is the number of event (invocations + backedges)
- // per millisecond.
- inline void update_rate(jlong t, Method* m);
- // Compute threshold scaling coefficient
- inline double threshold_scale(CompLevel level, int feedback_k);
- // If a method is old enough and is still in the interpreter we would want to
- // start profiling without waiting for the compiled method to arrive. This function
- // determines whether we should do that.
- inline bool should_create_mdo(Method* method, CompLevel cur_level);
- // Create MDO if necessary.
- void create_mdo(const methodHandle& mh, JavaThread* thread);
- // Is method profiled enough?
- bool is_method_profiled(Method* method);
-
- double _increase_threshold_at_ratio;
-
- bool maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread);
-
- int c1_count() const { return _c1_count; }
- int c2_count() const { return _c2_count; }
- void set_c1_count(int x) { _c1_count = x; }
- void set_c2_count(int x) { _c2_count = x; }
-
- enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
- void print_event(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
- // Print policy-specific information if necessary
- void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
- // Check if the method can be compiled, change level if necessary
- void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
- // Submit a given method for compilation
- void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
- // Simple methods are as good being compiled with C1 as C2.
- // This function tells if it's such a function.
- inline static bool is_trivial(Method* method);
- // Force method to be compiled at CompLevel_simple?
- inline static bool should_compile_at_level_simple(Method* method);
-
- // Predicate helpers are used by .*_predicate() methods as well as others.
- // They check the given counter values, multiplied by the scale against the thresholds.
- template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale, Method* method);
- template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale, Method* method);
-
- // Get a compilation level for a given method.
- static CompLevel comp_level(Method* method);
- void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
- CompLevel level, CompiledMethod* nm, JavaThread* thread);
- void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
- int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread);
-
- void set_increase_threshold_at_ratio() { _increase_threshold_at_ratio = 100 / (100 - (double)IncreaseFirstTierCompileThresholdAt); }
- void set_start_time(jlong t) { _start_time = t; }
- jlong start_time() const { return _start_time; }
-
-public:
- TieredThresholdPolicy() : _start_time(0), _c1_count(0), _c2_count(0) { }
- virtual int compiler_count(CompLevel comp_level) {
- if (is_c1_compile(comp_level)) return c1_count();
- if (is_c2_compile(comp_level)) return c2_count();
- return 0;
- }
- virtual CompLevel initial_compile_level() { return MIN2((CompLevel)TieredStopAtLevel, CompLevel_initial_compile); }
- virtual void do_safepoint_work() { }
- virtual void delay_compilation(Method* method) { }
- virtual void disable_compilation(Method* method) { }
- virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
- virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee,
- int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
- // Select task is called by CompileBroker. We should return a task or NULL.
- virtual CompileTask* select_task(CompileQueue* compile_queue);
- // Tell the runtime if we think a given method is adequately profiled.
- virtual bool is_mature(Method* method);
- // Initialize: set compiler thread count
- virtual void initialize();
- virtual bool should_not_inline(ciEnv* env, ciMethod* callee);
-};
-
-#endif // TIERED
-
-#endif // SHARE_RUNTIME_TIEREDTHRESHOLDPOLICY_HPP
--- a/src/hotspot/share/utilities/decoder.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/utilities/decoder.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -84,7 +84,7 @@
}
bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath, bool demangle) {
- bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ bool error_handling_thread = os::current_thread_id() == VMError::get_first_error_tid();
if (error_handling_thread) {
return get_error_handler_instance()->decode(addr, buf, buflen, offset, modulepath, demangle);
} else {
@@ -95,7 +95,7 @@
}
bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const void* base) {
- bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ bool error_handling_thread = os::current_thread_id() == VMError::get_first_error_tid();
if (error_handling_thread) {
return get_error_handler_instance()->decode(addr, buf, buflen, offset, base);
} else {
@@ -106,7 +106,7 @@
bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
- bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ bool error_handling_thread = os::current_thread_id() == VMError::get_first_error_tid();
if (error_handling_thread) {
return get_error_handler_instance()->demangle(symbol, buf, buflen);
} else {
--- a/src/hotspot/share/utilities/vmError.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/utilities/vmError.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -1205,7 +1205,7 @@
st->print_cr("END.");
}
-volatile intptr_t VMError::first_error_tid = -1;
+volatile intptr_t VMError::_first_error_tid = -1;
/** Expand a pattern into a buffer starting at pos and open a file using constructed path */
static int expand_and_open(const char* pattern, bool overwrite_existing, char* buf, size_t buflen, size_t pos) {
@@ -1355,8 +1355,8 @@
os::abort(CreateCoredumpOnCrash);
}
intptr_t mytid = os::current_thread_id();
- if (first_error_tid == -1 &&
- Atomic::cmpxchg(mytid, &first_error_tid, (intptr_t)-1) == -1) {
+ if (_first_error_tid == -1 &&
+ Atomic::cmpxchg(mytid, &_first_error_tid, (intptr_t)-1) == -1) {
// Initialize time stamps to use the same base.
out.time_stamp().update_to(1);
@@ -1416,7 +1416,7 @@
// This is not the first error, see if it happened in a different thread
// or in the same thread during error reporting.
- if (first_error_tid != mytid) {
+ if (_first_error_tid != mytid) {
char msgbuf[64];
jio_snprintf(msgbuf, sizeof(msgbuf),
"[thread " INTX_FORMAT " also had an error]",
--- a/src/hotspot/share/utilities/vmError.hpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/hotspot/share/utilities/vmError.hpp Wed Oct 16 11:23:46 2019 +0200
@@ -32,8 +32,6 @@
class VM_ReportJavaOutOfMemory;
class VMError : public AllStatic {
- friend class VM_ReportJavaOutOfMemory;
- friend class Decoder;
friend class VMStructs;
static int _id; // Solaris/Linux signals: 0 - SIGRTMAX
@@ -65,7 +63,7 @@
// Thread id of the first error. We must be able to handle native thread,
// so use thread id instead of Thread* to identify thread.
- static volatile intptr_t first_error_tid;
+ static volatile intptr_t _first_error_tid;
// Core dump status, false if we have been unable to write a core/minidump for some reason
static bool coredump_status;
@@ -177,9 +175,9 @@
static address get_resetted_sighandler(int sig);
// check to see if fatal error reporting is in progress
- static bool fatal_error_in_progress() { return first_error_tid != -1; }
+ static bool fatal_error_in_progress() { return _first_error_tid != -1; }
- static intptr_t get_first_error_tid() { return first_error_tid; }
+ static intptr_t get_first_error_tid() { return _first_error_tid; }
// Called by the WatcherThread to check if error reporting has timed-out.
// Returns true if error reporting has not completed within the ErrorLogTimeout limit.
--- a/src/java.base/share/classes/java/io/FilePermission.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/io/FilePermission.java Wed Oct 16 11:23:46 2019 +0200
@@ -367,12 +367,22 @@
this.mask = mask;
if (cpath.equals("<<ALL FILES>>")) {
+ allFiles = true;
directory = true;
recursive = true;
cpath = "";
return;
}
+ // Validate path by platform's default file system
+ try {
+ String name = cpath.endsWith("*") ? cpath.substring(0, cpath.length() - 1) + "-" : cpath;
+ builtInFS.getPath(new File(name).getPath());
+ } catch (InvalidPathException ipe) {
+ invalid = true;
+ return;
+ }
+
// store only the canonical cpath if possible
cpath = AccessController.doPrivileged(new PrivilegedAction<>() {
public String run() {
@@ -463,6 +473,9 @@
* <P>
* The default value of the {@code jdk.io.permissionsUseCanonicalPath}
* system property is {@code false} in this implementation.
+ * <p>
+ * The value can also be set with a security property using the same name,
+ * but setting a system property will override the security property value.
*
* @param path the pathname of the file/directory.
* @param actions the action string.
@@ -573,19 +586,19 @@
* @return the effective mask
*/
boolean impliesIgnoreMask(FilePermission that) {
+ if (this == that) {
+ return true;
+ }
+ if (allFiles) {
+ return true;
+ }
+ if (this.invalid || that.invalid) {
+ return false;
+ }
+ if (that.allFiles) {
+ return false;
+ }
if (FilePermCompat.nb) {
- if (this == that) {
- return true;
- }
- if (allFiles) {
- return true;
- }
- if (this.invalid || that.invalid) {
- return false;
- }
- if (that.allFiles) {
- return false;
- }
// Left at least same level of wildness as right
if ((this.recursive && that.recursive) != that.recursive
|| (this.directory && that.directory) != that.directory) {
@@ -783,10 +796,10 @@
FilePermission that = (FilePermission) obj;
+ if (this.invalid || that.invalid) {
+ return false;
+ }
if (FilePermCompat.nb) {
- if (this.invalid || that.invalid) {
- return false;
- }
return (this.mask == that.mask) &&
(this.allFiles == that.allFiles) &&
this.npath.equals(that.npath) &&
@@ -795,6 +808,7 @@
(this.recursive == that.recursive);
} else {
return (this.mask == that.mask) &&
+ (this.allFiles == that.allFiles) &&
this.cpath.equals(that.cpath) &&
(this.directory == that.directory) &&
(this.recursive == that.recursive);
--- a/src/java.base/share/classes/java/lang/ClassLoader.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2004,6 +2005,17 @@
return scl;
}
+ /*
+ * Initialize default paths for native libraries search.
+ * Must be done early as JDK may load libraries during bootstrap.
+ *
+ * @see java.lang.System#initPhase1
+ */
+ static void initLibraryPaths() {
+ usr_paths = initializePath("java.library.path");
+ sys_paths = initializePath("sun.boot.library.path");
+ }
+
// Returns true if the specified class loader can be found in this class
// loader's delegation chain.
boolean isAncestor(ClassLoader cl) {
@@ -2473,8 +2485,7 @@
*
* We use a static stack to hold the list of libraries we are
* loading because this can happen only when called by the
- * same thread because Runtime.load and Runtime.loadLibrary
- * are synchronous.
+ * same thread because this block is synchronous.
*
* If there is a pending load operation for the library, we
* immediately return success; otherwise, we raise
@@ -2619,10 +2630,9 @@
boolean isAbsolute) {
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
- if (sys_paths == null) {
- usr_paths = initializePath("java.library.path");
- sys_paths = initializePath("sun.boot.library.path");
- }
+ assert sys_paths != null : "should be initialized at this point";
+ assert usr_paths != null : "should be initialized at this point";
+
if (isAbsolute) {
if (loadLibrary0(fromClass, new File(name))) {
return;
--- a/src/java.base/share/classes/java/lang/Runtime.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/lang/Runtime.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -732,7 +733,7 @@
load0(Reflection.getCallerClass(), filename);
}
- synchronized void load0(Class<?> fromClass, String filename) {
+ void load0(Class<?> fromClass, String filename) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(filename);
@@ -794,14 +795,14 @@
loadLibrary0(Reflection.getCallerClass(), libname);
}
- synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+ void loadLibrary0(Class<?> fromClass, String libname) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(libname);
}
if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(
- "Directory separator should not appear in library name: " + libname);
+ "Directory separator should not appear in library name: " + libname);
}
ClassLoader.loadLibrary(fromClass, libname, false);
}
--- a/src/java.base/share/classes/java/lang/StringCoding.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/lang/StringCoding.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -191,6 +191,12 @@
return result.with(StringLatin1.inflate(ba, off, len), UTF16);
}
}
+ // fastpath for always Latin1 decodable single byte
+ if (COMPACT_STRINGS && cd instanceof ArrayDecoder && ((ArrayDecoder)cd).isLatin1Decodable()) {
+ byte[] dst = new byte[len];
+ ((ArrayDecoder)cd).decodeToLatin1(ba, off, len, dst);
+ return result.with(dst, LATIN1);
+ }
int en = scale(len, cd.maxCharsPerByte());
char[] ca = new char[en];
if (cd instanceof ArrayDecoder) {
@@ -278,6 +284,13 @@
((ArrayDecoder)cd).isASCIICompatible() && !hasNegatives(ba, off, len)) {
return decodeLatin1(ba, off, len);
}
+ // fastpath for always Latin1 decodable single byte
+ if (COMPACT_STRINGS && cd instanceof ArrayDecoder && ((ArrayDecoder)cd).isLatin1Decodable()) {
+ byte[] dst = new byte[len];
+ ((ArrayDecoder)cd).decodeToLatin1(ba, off, len, dst);
+ return new Result().with(dst, LATIN1);
+ }
+
int en = scale(len, cd.maxCharsPerByte());
if (len == 0) {
return new Result().with();
--- a/src/java.base/share/classes/java/lang/System.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/lang/System.java Wed Oct 16 11:23:46 2019 +0200
@@ -2045,6 +2045,8 @@
// register shared secrets
setJavaLangAccess();
+ ClassLoader.initLibraryPaths();
+
// Subsystems that are invoked during initialization can invoke
// VM.isBooted() in order to avoid doing things that should
// wait until the VM is fully initialized. The initialization level
--- a/src/java.base/share/classes/java/net/NetPermission.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/net/NetPermission.java Wed Oct 16 11:23:46 2019 +0200
@@ -145,6 +145,15 @@
* </tr>
*
* <tr>
+ * <th scope="row">setSocketImpl</th>
+ * <td>The ability to create a sub-class of Socket or ServerSocket with a
+ * user specified SocketImpl.</td>
+ * <td>Malicious user-defined SocketImpls can change the behavior of
+ * Socket and ServerSocket in surprising ways, by virtue of their
+ * ability to access the protected fields of SocketImpl.</td>
+ * </tr>
+ *
+ * <tr>
* <th scope="row">specifyStreamHandler</th>
* <td>The ability
* to specify a stream handler when constructing a URL</td>
--- a/src/java.base/share/classes/java/net/ServerSocket.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/net/ServerSocket.java Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
import java.util.Set;
import java.util.Collections;
+import sun.security.util.SecurityConstants;
import sun.net.PlatformSocketImpl;
/**
@@ -73,13 +74,25 @@
*
* @throws NullPointerException if impl is {@code null}.
*
+ * @throws SecurityException if a security manager is set and
+ * its {@code checkPermission} method doesn't allow
+ * {@code NetPermission("setSocketImpl")}.
* @since 12
*/
protected ServerSocket(SocketImpl impl) {
Objects.requireNonNull(impl);
+ checkPermission();
this.impl = impl;
}
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ return null;
+ }
+
/**
* Creates an unbound server socket.
*
--- a/src/java.base/share/classes/java/net/Socket.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/net/Socket.java Wed Oct 16 11:23:46 2019 +0200
@@ -25,6 +25,8 @@
package java.net;
+import sun.security.util.SecurityConstants;
+
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
@@ -182,12 +184,28 @@
*
* @throws SocketException if there is an error in the underlying protocol,
* such as a TCP error.
+ *
+ * @throws SecurityException if {@code impl} is non-null and a security manager is set
+ * and its {@code checkPermission} method doesn't allow {@code NetPermission("setSocketImpl")}.
+ *
* @since 1.1
*/
protected Socket(SocketImpl impl) throws SocketException {
+ checkPermission(impl);
this.impl = impl;
}
+ private static Void checkPermission(SocketImpl impl) {
+ if (impl == null) {
+ return null;
+ }
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ return null;
+ }
+
/**
* Creates a stream socket and connects it to the specified port
* number on the named host.
--- a/src/java.base/share/classes/java/net/URL.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/net/URL.java Wed Oct 16 11:23:46 2019 +0200
@@ -484,6 +484,16 @@
throw new MalformedURLException(s);
}
}
+ if ("jar".equalsIgnoreCase(protocol)) {
+ if (handler instanceof sun.net.www.protocol.jar.Handler) {
+ // URL.openConnection() would throw a confusing exception
+ // so generate a better exception here instead.
+ String s = ((sun.net.www.protocol.jar.Handler) handler).checkNestedProtocol(file);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
+ }
+ }
}
/**
--- a/src/java.base/share/classes/java/text/DecimalFormat.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/text/DecimalFormat.java Wed Oct 16 11:23:46 2019 +0200
@@ -2756,7 +2756,10 @@
/**
* Return the grouping size. Grouping size is the number of digits between
* grouping separators in the integer portion of a number. For example,
- * in the number "123,456.78", the grouping size is 3.
+ * in the number "123,456.78", the grouping size is 3. Grouping size of
+ * zero designates that grouping is not used, which provides the same
+ * formatting as if calling {@link #setGroupingUsed(boolean)
+ * setGroupingUsed(false)}.
*
* @return the grouping size
* @see #setGroupingSize
@@ -2770,16 +2773,28 @@
/**
* Set the grouping size. Grouping size is the number of digits between
* grouping separators in the integer portion of a number. For example,
- * in the number "123,456.78", the grouping size is 3.
- * <br>
+ * in the number "123,456.78", the grouping size is 3. Grouping size of
+ * zero designates that grouping is not used, which provides the same
+ * formatting as if calling {@link #setGroupingUsed(boolean)
+ * setGroupingUsed(false)}.
+ * <p>
* The value passed in is converted to a byte, which may lose information.
+ * Values that are negative or greater than
+ * {@link java.lang.Byte#MAX_VALUE Byte.MAX_VALUE}, will throw an
+ * {@code IllegalArgumentException}.
*
* @param newValue the new grouping size
* @see #getGroupingSize
* @see java.text.NumberFormat#setGroupingUsed
* @see java.text.DecimalFormatSymbols#setGroupingSeparator
+ * @throws IllegalArgumentException if {@code newValue} is negative or
+ * greater than {@link java.lang.Byte#MAX_VALUE Byte.MAX_VALUE}
*/
public void setGroupingSize (int newValue) {
+ if (newValue < 0 || newValue > Byte.MAX_VALUE) {
+ throw new IllegalArgumentException(
+ "newValue is out of valid range. value: " + newValue);
+ }
groupingSize = (byte)newValue;
fastPathCheckNeeded = true;
}
@@ -3906,6 +3921,12 @@
// Didn't have exponential fields
useExponentialNotation = false;
}
+
+ // Restore the invariant value if groupingSize is invalid.
+ if (groupingSize < 0) {
+ groupingSize = 3;
+ }
+
serialVersionOnStream = currentSerialVersion;
}
@@ -4009,14 +4030,15 @@
/**
* The number of digits between grouping separators in the integer
- * portion of a number. Must be greater than 0 if
+ * portion of a number. Must be non-negative and less than or equal to
+ * {@link java.lang.Byte#MAX_VALUE Byte.MAX_VALUE} if
* {@code NumberFormat.groupingUsed} is true.
*
* @serial
* @see #getGroupingSize
* @see java.text.NumberFormat#isGroupingUsed
*/
- private byte groupingSize = 3; // invariant, > 0 if useThousands
+ private byte groupingSize = 3; // invariant, 0 - 127, if groupingUsed
/**
* If true, forces the decimal separator to always appear in a formatted
--- a/src/java.base/share/classes/java/util/regex/Pattern.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java Wed Oct 16 11:23:46 2019 +0200
@@ -1427,7 +1427,11 @@
localTCNCount = 0;
if (!pattern.isEmpty()) {
- compile();
+ try {
+ compile();
+ } catch (StackOverflowError soe) {
+ throw error("Stack overflow during pattern compilation");
+ }
} else {
root = new Start(lastAccept);
matchRoot = lastAccept;
@@ -1965,6 +1969,10 @@
int ch = temp[cursor++];
while (ch != 0 && !isLineSeparator(ch))
ch = temp[cursor++];
+ if (ch == 0 && cursor > patternLength) {
+ cursor = patternLength;
+ ch = temp[cursor++];
+ }
return ch;
}
@@ -1975,6 +1983,10 @@
int ch = temp[++cursor];
while (ch != 0 && !isLineSeparator(ch))
ch = temp[++cursor];
+ if (ch == 0 && cursor > patternLength) {
+ cursor = patternLength;
+ ch = temp[cursor];
+ }
return ch;
}
@@ -3415,9 +3427,10 @@
private int N() {
if (read() == '{') {
int i = cursor;
- while (cursor < patternLength && read() != '}') {}
- if (cursor > patternLength)
- throw error("Unclosed character name escape sequence");
+ while (read() != '}') {
+ if (cursor >= patternLength)
+ throw error("Unclosed character name escape sequence");
+ }
String name = new String(temp, i, cursor - i - 1);
try {
return Character.codePointOf(name);
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 16 11:23:46 2019 +0200
@@ -2171,6 +2171,10 @@
} while (retryTunnel < maxRedirects);
if (retryTunnel >= maxRedirects || (respCode != HTTP_OK)) {
+ if (respCode != HTTP_PROXY_AUTH) {
+ // remove all but authenticate responses
+ responses.reset();
+ }
throw new IOException("Unable to tunnel through proxy."+
" Proxy returns \"" +
statusLine + "\"");
--- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, 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
@@ -121,6 +121,13 @@
return h;
}
+ public String checkNestedProtocol(String spec) {
+ if (spec.regionMatches(true, 0, "jar:", 0, 4)) {
+ return "Nested JAR URLs are not supported";
+ } else {
+ return null;
+ }
+ }
@Override
@SuppressWarnings("deprecation")
@@ -146,6 +153,12 @@
: false;
spec = spec.substring(start, limit);
+ String exceptionMessage = checkNestedProtocol(spec);
+ if (exceptionMessage != null) {
+ // NPE will be transformed into MalformedURLException by the caller
+ throw new NullPointerException(exceptionMessage);
+ }
+
if (absoluteSpec) {
file = parseAbsoluteSpec(spec);
} else if (!refOnly) {
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java Wed Oct 16 11:23:46 2019 +0200
@@ -37,6 +37,9 @@
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.Set;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -59,7 +62,12 @@
private volatile int timeout;
static ServerSocket create(ServerSocketChannelImpl ssc) {
- return new ServerSocketAdaptor(ssc);
+ PrivilegedExceptionAction<ServerSocket> pa = () -> new ServerSocketAdaptor(ssc);
+ try {
+ return AccessController.doPrivileged(pa);
+ } catch (PrivilegedActionException pae) {
+ throw new InternalError("Should not reach here", pae);
+ }
}
private ServerSocketAdaptor(ServerSocketChannelImpl ssc) {
--- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Wed Oct 16 11:23:46 2019 +0200
@@ -36,6 +36,9 @@
import java.net.SocketOption;
import java.net.StandardSocketOptions;
import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.Set;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -61,10 +64,11 @@
}
static Socket create(SocketChannelImpl sc) {
+ PrivilegedExceptionAction<Socket> pa = () -> new SocketAdaptor(sc);
try {
- return new SocketAdaptor(sc);
- } catch (SocketException e) {
- throw new InternalError("Should not reach here");
+ return AccessController.doPrivileged(pa);
+ } catch (PrivilegedActionException pae) {
+ throw new InternalError("Should not reach here", pae);
}
}
--- a/src/java.base/share/classes/sun/nio/cs/ArrayDecoder.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/cs/ArrayDecoder.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 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
@@ -28,6 +28,9 @@
/*
* FastPath byte[]->char[] decoder, REPLACE on malformed or
* unmappable input.
+ *
+ * FastPath encoded byte[]-> "String Latin1 coding" byte[] decoder for use when
+ * charset is always decodable to the internal String Latin1 coding byte[], ie. all mappings <=0xff
*/
public interface ArrayDecoder {
@@ -36,4 +39,14 @@
default boolean isASCIICompatible() {
return false;
}
+
+ // Is always decodable to internal String Latin1 coding, ie. all mappings <= 0xff
+ default boolean isLatin1Decodable() {
+ return false;
+ }
+
+ // Decode to internal String Latin1 coding byte[] fastpath for when isLatin1Decodable == true
+ default int decodeToLatin1(byte[] src, int sp, int len, byte[] dst) {
+ return 0;
+ }
}
--- a/src/java.base/share/classes/sun/nio/cs/SingleByte.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/cs/SingleByte.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -50,17 +50,27 @@
implements ArrayDecoder {
private final char[] b2c;
private final boolean isASCIICompatible;
+ private final boolean isLatin1Decodable;
public Decoder(Charset cs, char[] b2c) {
super(cs, 1.0f, 1.0f);
this.b2c = b2c;
this.isASCIICompatible = false;
+ this.isLatin1Decodable = false;
}
public Decoder(Charset cs, char[] b2c, boolean isASCIICompatible) {
super(cs, 1.0f, 1.0f);
this.b2c = b2c;
this.isASCIICompatible = isASCIICompatible;
+ this.isLatin1Decodable = false;
+ }
+
+ public Decoder(Charset cs, char[] b2c, boolean isASCIICompatible, boolean isLatin1Decodable) {
+ super(cs, 1.0f, 1.0f);
+ this.b2c = b2c;
+ this.isASCIICompatible = isASCIICompatible;
+ this.isLatin1Decodable = isLatin1Decodable;
}
private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
@@ -125,6 +135,18 @@
}
@Override
+ public int decodeToLatin1(byte[] src, int sp, int len, byte[] dst) {
+ if (len > dst.length)
+ len = dst.length;
+
+ int dp = 0;
+ while (dp < len) {
+ dst[dp++] = (byte)decode(src[sp++]);
+ }
+ return dp;
+ }
+
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
if (len > dst.length)
len = dst.length;
@@ -143,6 +165,11 @@
public boolean isASCIICompatible() {
return isASCIICompatible;
}
+
+ @Override
+ public boolean isLatin1Decodable() {
+ return isLatin1Decodable;
+ }
}
public static final class Encoder extends CharsetEncoder
--- a/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java Wed Oct 16 11:23:46 2019 +0200
@@ -201,7 +201,7 @@
// Primary XDH (RFC 7748) curves
NamedGroup.X25519,
- // Primary NIST curves (e.g. used in TLSv1.3)
+ // Primary NIST Suite B curves
NamedGroup.SECP256_R1,
NamedGroup.SECP384_R1,
NamedGroup.SECP521_R1,
@@ -209,17 +209,6 @@
// Secondary XDH curves
NamedGroup.X448,
- // Secondary NIST curves
- NamedGroup.SECT283_K1,
- NamedGroup.SECT283_R1,
- NamedGroup.SECT409_K1,
- NamedGroup.SECT409_R1,
- NamedGroup.SECT571_K1,
- NamedGroup.SECT571_R1,
-
- // non-NIST curves
- NamedGroup.SECP256_K1,
-
// FFDHE (RFC 7919)
NamedGroup.FFDHE_2048,
NamedGroup.FFDHE_3072,
--- a/src/java.base/share/classes/sun/security/util/FilePermCompat.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/security/util/FilePermCompat.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -42,8 +42,11 @@
public static final boolean compat;
static {
- String flag = GetPropertyAction.privilegedGetProperty(
- "jdk.io.permissionsUseCanonicalPath", "false");
+ String flag = SecurityProperties.privilegedGetOverridable(
+ "jdk.io.permissionsUseCanonicalPath");
+ if (flag == null) {
+ flag = "false";
+ }
switch (flag) {
case "true":
nb = false;
--- a/src/java.base/share/classes/sun/security/util/SecurityConstants.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/classes/sun/security/util/SecurityConstants.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, 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
@@ -97,6 +97,10 @@
public static final NetPermission GET_RESPONSECACHE_PERMISSION =
new NetPermission("getResponseCache");
+ // java.net.ServerSocket, java.net.Socket
+ public static final NetPermission SET_SOCKETIMPL_PERMISSION =
+ new NetPermission("setSocketImpl");
+
// java.lang.SecurityManager, sun.applet.AppletPanel
public static final RuntimePermission CREATE_CLASSLOADER_PERMISSION =
new RuntimePermission("createClassLoader");
--- a/src/java.base/share/conf/security/java.security Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/share/conf/security/java.security Wed Oct 16 11:23:46 2019 +0200
@@ -1213,3 +1213,51 @@
# if this property is not enabled.
#
jdk.security.caDistrustPolicies=SYMANTEC_TLS
+
+#
+# FilePermission path canonicalization
+#
+# This security property dictates how the path argument is processed and stored
+# while constructing a FilePermission object. If the value is set to true, the
+# path argument is canonicalized and FilePermission methods (such as implies,
+# equals, and hashCode) are implemented based on this canonicalized result.
+# Otherwise, the path argument is not canonicalized and FilePermission methods are
+# implemented based on the original input. See the implementation note of the
+# FilePermission class for more details.
+#
+# If a system property of the same name is also specified, it supersedes the
+# security property value defined here.
+#
+# The default value for this property is false.
+#
+jdk.io.permissionsUseCanonicalPath=false
+
+
+#
+# Policies for the proxy_impersonator Kerberos ccache configuration entry
+#
+# The proxy_impersonator ccache configuration entry indicates that the ccache
+# is a synthetic delegated credential for use with S4U2Proxy by an intermediate
+# server. The ccache file should also contain the TGT of this server and
+# an evidence ticket from the default principal of the ccache to this server.
+#
+# This security property determines how Java uses this configuration entry.
+# There are 3 possible values:
+#
+# no-impersonate - Ignore this configuration entry, and always act as
+# the owner of the TGT (if it exists).
+#
+# try-impersonate - Try impersonation when this configuration entry exists.
+# If no matching TGT or evidence ticket is found,
+# fallback to no-impersonate.
+#
+# always-impersonate - Always impersonate when this configuration entry exists.
+# If no matching TGT or evidence ticket is found,
+# no initial credential is read from the ccache.
+#
+# The default value is "always-impersonate".
+#
+# If a system property of the same name is also specified, it supersedes the
+# security property value defined here.
+#
+#jdk.security.krb5.default.initiate.credential=always-impersonate
--- a/src/java.base/unix/native/libnio/ch/Net.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/unix/native/libnio/ch/Net.c Wed Oct 16 11:23:46 2019 +0200
@@ -66,34 +66,6 @@
#endif
#endif
-#if defined(_AIX)
- #ifndef IP_BLOCK_SOURCE
- #define IP_BLOCK_SOURCE 58 /* Block data from a given source to a given group */
- #define IP_UNBLOCK_SOURCE 59 /* Unblock data from a given source to a given group */
- #define IP_ADD_SOURCE_MEMBERSHIP 60 /* Join a source-specific group */
- #define IP_DROP_SOURCE_MEMBERSHIP 61 /* Leave a source-specific group */
- #endif
-
- #ifndef MCAST_BLOCK_SOURCE
- #define MCAST_BLOCK_SOURCE 64
- #define MCAST_UNBLOCK_SOURCE 65
- #define MCAST_JOIN_SOURCE_GROUP 66
- #define MCAST_LEAVE_SOURCE_GROUP 67
-
- /* This means we're on AIX 5.3 and 'group_source_req' and 'ip_mreq_source' aren't defined as well */
- struct group_source_req {
- uint32_t gsr_interface;
- struct sockaddr_storage gsr_group;
- struct sockaddr_storage gsr_source;
- };
- struct ip_mreq_source {
- struct in_addr imr_multiaddr; /* IP multicast address of group */
- struct in_addr imr_sourceaddr; /* IP address of source */
- struct in_addr imr_interface; /* local IP address of interface */
- };
- #endif
-#endif /* _AIX */
-
#define COPY_INET6_ADDRESS(env, source, target) \
(*env)->GetByteArrayRegion(env, source, 0, 16, target)
--- a/src/java.base/windows/classes/java/lang/ProcessImpl.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.base/windows/classes/java/lang/ProcessImpl.java Wed Oct 16 11:23:46 2019 +0200
@@ -38,6 +38,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@@ -46,6 +47,8 @@
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
+import sun.security.action.GetBooleanAction;
+import sun.security.action.GetPropertyAction;
/* This class is for the exclusive use of ProcessBuilder.start() to
* create new processes.
@@ -209,12 +212,15 @@
private static final int VERIFICATION_CMD_BAT = 0;
private static final int VERIFICATION_WIN32 = 1;
- private static final int VERIFICATION_LEGACY = 2;
+ private static final int VERIFICATION_WIN32_SAFE = 2; // inside quotes not allowed
+ private static final int VERIFICATION_LEGACY = 3;
+ // See Command shell overview for documentation of special characters.
+ // https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490954(v=technet.10)
private static final char ESCAPE_VERIFICATION[][] = {
// We guarantee the only command file execution for implicit [cmd.exe] run.
// http://technet.microsoft.com/en-us/library/bb490954.aspx
{' ', '\t', '<', '>', '&', '|', '^'},
-
+ {' ', '\t', '<', '>'},
{' ', '\t', '<', '>'},
{' ', '\t'}
};
@@ -231,8 +237,25 @@
cmdbuf.append(' ');
String s = cmd[i];
if (needsEscaping(verificationType, s)) {
- cmdbuf.append('"').append(s);
+ cmdbuf.append('"');
+ if (verificationType == VERIFICATION_WIN32_SAFE) {
+ // Insert the argument, adding '\' to quote any interior quotes
+ int length = s.length();
+ for (int j = 0; j < length; j++) {
+ char c = s.charAt(j);
+ if (c == DOUBLEQUOTE) {
+ int count = countLeadingBackslash(verificationType, s, j);
+ while (count-- > 0) {
+ cmdbuf.append(BACKSLASH); // double the number of backslashes
+ }
+ cmdbuf.append(BACKSLASH); // backslash to quote the quote
+ }
+ cmdbuf.append(c);
+ }
+ } else {
+ cmdbuf.append(s);
+ }
// The code protects the [java.exe] and console command line
// parser, that interprets the [\"] combination as an escape
// sequence for the ["] char.
@@ -245,8 +268,9 @@
// command line parser. The case of the [""] tail escape
// sequence could not be realized due to the argument validation
// procedure.
- if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
- cmdbuf.append('\\');
+ int count = countLeadingBackslash(verificationType, s, s.length());
+ while (count-- > 0) {
+ cmdbuf.append(BACKSLASH); // double the number of backslashes
}
cmdbuf.append('"');
} else {
@@ -256,26 +280,16 @@
return cmdbuf.toString();
}
- private static boolean isQuoted(boolean noQuotesInside, String arg,
- String errorMessage) {
- int lastPos = arg.length() - 1;
- if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
- // The argument has already been quoted.
- if (noQuotesInside) {
- if (arg.indexOf('"', 1) != lastPos) {
- // There is ["] inside.
- throw new IllegalArgumentException(errorMessage);
- }
- }
- return true;
- }
- if (noQuotesInside) {
- if (arg.indexOf('"') >= 0) {
- // There is ["] inside.
- throw new IllegalArgumentException(errorMessage);
- }
- }
- return false;
+ /**
+ * Return the argument without quotes (1st and last) if present, else the arg.
+ * @param str a string
+ * @return the string without 1st and last quotes
+ */
+ private static String unQuote(String str) {
+ int len = str.length();
+ return (len >= 2 && str.charAt(0) == DOUBLEQUOTE && str.charAt(len - 1) == DOUBLEQUOTE)
+ ? str.substring(1, len - 1)
+ : str;
}
private static boolean needsEscaping(int verificationType, String arg) {
@@ -286,9 +300,26 @@
// For [.exe] or [.com] file the unpaired/internal ["]
// in the argument is not a problem.
- boolean argIsQuoted = isQuoted(
- (verificationType == VERIFICATION_CMD_BAT),
- arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+ String unquotedArg = unQuote(arg);
+ boolean argIsQuoted = !arg.equals(unquotedArg);
+ boolean embeddedQuote = unquotedArg.indexOf(DOUBLEQUOTE) >= 0;
+
+ switch (verificationType) {
+ case VERIFICATION_CMD_BAT:
+ if (embeddedQuote) {
+ throw new IllegalArgumentException("Argument has embedded quote, " +
+ "use the explicit CMD.EXE call.");
+ }
+ break; // break determine whether to quote
+ case VERIFICATION_WIN32_SAFE:
+ if (argIsQuoted && embeddedQuote) {
+ throw new IllegalArgumentException("Malformed argument has embedded quote: "
+ + unquotedArg);
+ }
+ break;
+ default:
+ break;
+ }
if (!argIsQuoted) {
char testEscape[] = ESCAPE_VERIFICATION[verificationType];
@@ -304,13 +335,13 @@
private static String getExecutablePath(String path)
throws IOException
{
- boolean pathIsQuoted = isQuoted(true, path,
- "Executable name has embedded quote, split the arguments");
-
+ String name = unQuote(path);
+ if (name.indexOf(DOUBLEQUOTE) >= 0) {
+ throw new IllegalArgumentException("Executable name has embedded quote, " +
+ "split the arguments: " + name);
+ }
// Win32 CreateProcess requires path to be normalized
- File fileToRun = new File(pathIsQuoted
- ? path.substring(1, path.length() - 1)
- : path);
+ File fileToRun = new File(name);
// From the [CreateProcess] function documentation:
//
@@ -325,13 +356,26 @@
// sequence:..."
//
// In practice ANY non-existent path is extended by [.exe] extension
- // in the [CreateProcess] funcion with the only exception:
+ // in the [CreateProcess] function with the only exception:
// the path ends by (.)
return fileToRun.getPath();
}
+ /**
+ * An executable is any program that is an EXE or does not have an extension
+ * and the Windows createProcess will be looking for .exe.
+ * The comparison is case insensitive based on the name.
+ * @param executablePath the executable file
+ * @return true if the path ends in .exe or does not have an extension.
+ */
+ private boolean isExe(String executablePath) {
+ File file = new File(executablePath);
+ String upName = file.getName().toUpperCase(Locale.ROOT);
+ return (upName.endsWith(".EXE") || upName.indexOf('.') < 0);
+ }
+ // Old version that can be bypassed
private boolean isShellFile(String executablePath) {
String upPath = executablePath.toUpperCase();
return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
@@ -342,6 +386,21 @@
return argbuf.append('"').append(arg).append('"').toString();
}
+ // Count backslashes before start index of string.
+ // .bat files don't include backslashes as part of the quote
+ private static int countLeadingBackslash(int verificationType,
+ CharSequence input, int start) {
+ if (verificationType == VERIFICATION_CMD_BAT)
+ return 0;
+ int j;
+ for (j = start - 1; j >= 0 && input.charAt(j) == BACKSLASH; j--) {
+ // just scanning backwards
+ }
+ return (start - 1) - j; // number of BACKSLASHES
+ }
+
+ private static final char DOUBLEQUOTE = '\"';
+ private static final char BACKSLASH = '\\';
private final long handle;
private final ProcessHandle processHandle;
@@ -358,15 +417,13 @@
throws IOException
{
String cmdstr;
- SecurityManager security = System.getSecurityManager();
- boolean allowAmbiguousCommands = false;
- if (security == null) {
- allowAmbiguousCommands = true;
- String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
- if (value != null)
- allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
- }
- if (allowAmbiguousCommands) {
+ final SecurityManager security = System.getSecurityManager();
+ final String value = GetPropertyAction.
+ privilegedGetProperty("jdk.lang.Process.allowAmbiguousCommands",
+ (security == null ? "true" : "false"));
+ final boolean allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
+
+ if (allowAmbiguousCommands && security == null) {
// Legacy mode.
// Normalize path if possible.
@@ -413,11 +470,12 @@
// Quotation protects from interpretation of the [path] argument as
// start of longer path with spaces. Quotation has no influence to
// [.exe] extension heuristic.
+ boolean isShell = allowAmbiguousCommands ? isShellFile(executablePath)
+ : !isExe(executablePath);
cmdstr = createCommandLine(
- // We need the extended verification procedure for CMD files.
- isShellFile(executablePath)
- ? VERIFICATION_CMD_BAT
- : VERIFICATION_WIN32,
+ // We need the extended verification procedures
+ isShell ? VERIFICATION_CMD_BAT
+ : (allowAmbiguousCommands ? VERIFICATION_WIN32 : VERIFICATION_WIN32_SAFE),
quoteString(executablePath),
cmd);
}
--- a/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeType.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeType.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -346,9 +346,9 @@
return newObj;
}
- private String primaryType;
- private String subType;
- private MimeTypeParameterList parameters;
+ private transient String primaryType;
+ private transient String subType;
+ private transient MimeTypeParameterList parameters;
// below here be scary parsing related things
--- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Wed Oct 16 11:23:46 2019 +0200
@@ -61,6 +61,10 @@
public CGraphicsDevice(final int displayID) {
this.displayID = displayID;
config = CGLGraphicsConfig.getConfig(this, displayID, 0);
+ // initializes default device state, might be redundant step since we
+ // call "displayChanged()" later anyway, but we do not want to leave the
+ // device in an inconsistent state after construction
+ displayChanged();
}
/**
--- a/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java Wed Oct 16 11:23:46 2019 +0200
@@ -25,7 +25,6 @@
package sun.java2d.opengl;
-import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
@@ -33,9 +32,7 @@
import java.awt.Rectangle;
import java.awt.image.ColorModel;
-import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
-
import sun.lwawt.macosx.CPlatformView;
public abstract class CGLSurfaceData extends OGLSurfaceData {
@@ -342,43 +339,4 @@
return offscreenImage;
}
}
-
- // Mac OS X specific APIs for JOGL/Java2D bridge...
-
- // given a surface create and attach GL context, then return it
- private static native long createCGLContextOnSurface(CGLSurfaceData sd,
- long sharedContext);
-
- public static long createOGLContextOnSurface(Graphics g, long sharedContext) {
- SurfaceData sd = ((SunGraphics2D) g).surfaceData;
- if ((sd instanceof CGLSurfaceData) == true) {
- CGLSurfaceData cglsd = (CGLSurfaceData) sd;
- return createCGLContextOnSurface(cglsd, sharedContext);
- } else {
- return 0L;
- }
- }
-
- // returns whether or not the makeCurrent operation succeeded
- static native boolean makeCGLContextCurrentOnSurface(CGLSurfaceData sd,
- long ctx);
-
- public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
- SurfaceData sd = ((SunGraphics2D) g).surfaceData;
- if ((ctx != 0L) && ((sd instanceof CGLSurfaceData) == true)) {
- CGLSurfaceData cglsd = (CGLSurfaceData) sd;
- return makeCGLContextCurrentOnSurface(cglsd, ctx);
- } else {
- return false;
- }
- }
-
- // additional cleanup
- private static native void destroyCGLContext(long ctx);
-
- public static void destroyOGLContext(long ctx) {
- if (ctx != 0L) {
- destroyCGLContext(ctx);
- }
- }
}
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -444,6 +444,7 @@
fontHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
desktopProperties.put(SunToolkit.DESKTOPFONTHINTS, fontHints);
desktopProperties.put("awt.mouse.numButtons", BUTTONS);
+ desktopProperties.put("awt.multiClickInterval", getMultiClickTime());
// These DnD properties must be set, otherwise Swing ends up spewing NPEs
// all over the place. The values came straight off of MToolkit.
@@ -538,6 +539,11 @@
return BUTTONS;
}
+ /**
+ * Returns the double-click time interval in ms.
+ */
+ private static native int getMultiClickTime();
+
@Override
public boolean isTraySupported() {
return true;
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -831,3 +831,19 @@
}
return JNI_FALSE;
}
+
+/*
+ * Class: sun_lwawt_macosx_LWCToolkit
+ * Method: getMultiClickTime
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_sun_lwawt_macosx_LWCToolkit_getMultiClickTime(JNIEnv *env, jclass klass) {
+ __block jint multiClickTime = 0;
+ JNF_COCOA_ENTER(env);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ multiClickTime = (jint)([NSEvent doubleClickInterval] * 1000);
+ }];
+ JNF_COCOA_EXIT(env);
+ return multiClickTime;
+}
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m Wed Oct 16 11:23:46 2019 +0200
@@ -152,7 +152,6 @@
AWT_ASSERT_APPKIT_THREAD;
jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
- jint pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue];
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
[argValue removeAllObjects];
@@ -161,11 +160,7 @@
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
if (sharedContext == NULL) {
- if (glMask == 0) {
- glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
- }
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAAllowOfflineRenderers,
@@ -176,16 +171,17 @@
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 16,
- NSOpenGLPFAScreenMask, glMask,
0
};
sharedPixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if (sharedPixelFormat == nil) {
- J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
- [argValue addObject: [NSNumber numberWithLong: 0L]];
- return;
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
+
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
}
sharedContext =
--- a/src/java.desktop/share/classes/java/awt/Font.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/java/awt/Font.java Wed Oct 16 11:23:46 2019 +0200
@@ -1929,6 +1929,7 @@
// value is the default.
if (fRequestedAttributes != null) {
+ try {
values = getAttributeValues(); // init
AttributeValues extras =
AttributeValues.fromSerializableHashtable(fRequestedAttributes);
@@ -1938,10 +1939,13 @@
values = getAttributeValues().merge(extras);
this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
this.hasLayoutAttributes = values.anyNonDefault(LAYOUT_MASK);
-
+ } catch (Throwable t) {
+ throw new IOException(t);
+ } finally {
fRequestedAttributes = null; // don't need it any more
}
}
+ }
/**
* Returns the number of glyphs in this {@code Font}. Glyph codes
--- a/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>AWT Threading Issues</title>
</head>
<!--
- Copyright (c) 2002, 2018, 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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>AWT Threading Issues</h1>
<a id="ListenersThreads"></a>
@@ -192,6 +193,7 @@
<cite>The Java™ Virtual Machine Specification</cite>
guarantees
that the JVM doesn't exit until this thread terminates.
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html Wed Oct 16 11:23:46 2019 +0200
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>AWT Desktop Properties</h1>
The following refers to standard AWT desktop properties that
@@ -277,6 +278,7 @@
This property should be used when there is no need in listening mouse events fired as a result of
activity with extra mouse button.
By default this property is set to {@code true}.
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>The AWT Focus Subsystem</title>
</head>
<!--
- 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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+ <div class="contentContainer">
<h1>The AWT Focus Subsystem</h1>
<p>
@@ -1362,6 +1363,7 @@
change requests in all cases. Previously, requests were granted
for heavyweights, but denied for lightweights.
</ol>
+ </div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/java/awt/doc-files/Modality.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/java/awt/doc-files/Modality.html Wed Oct 16 11:23:46 2019 +0200
@@ -35,6 +35,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>The AWT Modality</h1>
<p>
@@ -440,5 +441,6 @@
<img src="modal-example4.gif" alt="Example 4">
</p>
<br style="clear:both;">
+</div>
</main>
</body></html>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/bmp_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/bmp_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>BMP Metadata Format Specification</title>
</head>
<!--
-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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>BMP Metadata Format Specification</h1>
The XML schema for the native image metadata format is as follows:
@@ -161,5 +162,6 @@
</pre>
@since 1.5
+</div>
</main>
</body>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>GIF Metadata Format Specification</h1>
<a id="gif_stream_metadata_format"></a>
<h2>GIF Stream Metadata Format Specification</h2>
@@ -462,6 +463,7 @@
</tr>
</tbody>
</table>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>JPEG Metadata Format Specification and Usage Notes</title>
</head>
<!--
-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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>JPEG Metadata Format Specification and Usage Notes</h1>
<p>
@@ -1159,6 +1160,7 @@
<!-- All elements are as defined above for image metadata -->
]>
</pre>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/png_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/png_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>PNG Metadata Format Specification</title>
</head>
<!--
-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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>PNG Metadata Format Specification</h1>
<p>
@@ -561,6 +562,7 @@
<!-- Data type: String -->
]>
</pre>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/standard_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/standard_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>Standard Metadata Format Specification</title>
</head>
<!--
-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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>Standard (Plug-in Neutral) Metadata Format Specification</h1>
<p> The plug-in neutral "javax_imageio_1.0" format consists
@@ -394,6 +395,7 @@
<!-- Data type: Integer -->
]>
</pre>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>TIFF Metadata Format Specification and Usage Notes</h1>
<a href="#Reading">Reading Images</a>
@@ -1235,6 +1236,7 @@
</pre>
@since 9
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/wbmp_metadata.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/wbmp_metadata.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>WBMP Metadata Format Specification</title>
</head>
<!--
-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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>WBMP Metadata Format Specification</h1>
The XML schema for the native image metadata format is as follows:
@@ -63,5 +64,6 @@
</pre>
@since 1.5
+</div>
</main>
</body>
--- a/src/java.desktop/share/classes/javax/swing/plaf/multi/doc-files/multi_tsc.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/swing/plaf/multi/doc-files/multi_tsc.html Wed Oct 16 11:23:46 2019 +0200
@@ -5,7 +5,7 @@
<title>Using the Multiplexing Look and Feel</title>
</head>
<!--
- 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
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>Using the Multiplexing Look and Feel</h1>
<blockquote>
@@ -495,6 +496,7 @@
of auxiliary look and feels will most likely have developed and
tested against our Multiplexing look and feel.
</p>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html Wed Oct 16 11:23:46 2019 +0200
@@ -31,6 +31,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>Colors Used in Nimbus Look and Feel</h1>
<h2 id="primaryColors">Primary Colors</h2>
<table>
@@ -236,6 +237,7 @@
</tr>
</tbody>
</table>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/componentProperties.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/componentProperties.html Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
<body>
<main role="main">
+<div class="contentContainer">
<h1>Component Specific Properties</h1>
<p> The look, and to some degree the feel of Synth
can be customized by way of component specific properties.
@@ -1345,6 +1346,7 @@
<p><code>Prefix</code> is one of: EditorPane, FormattedTextField,
PasswordField, TextArea, TextField or TextPane.<br>
</p>
+</div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html Wed Oct 16 11:23:46 2019 +0200
@@ -46,6 +46,7 @@
<body>
<main role="main">
+ <div class="contentContainer">
<h1><a id="file">File Format</a></h1>
<p>
Synth's file format (<a href="synth.dtd">dtd</a>)
@@ -1030,6 +1031,7 @@
</synth>
</pre>
</div>
+ </div>
</main>
</body>
</html>
--- a/src/java.desktop/share/classes/sun/font/CMap.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/sun/font/CMap.java Wed Oct 16 11:23:46 2019 +0200
@@ -130,7 +130,7 @@
static final char noSuchChar = (char)0xfffd;
static final int SHORTMASK = 0x0000ffff;
- static final int INTMASK = 0xffffffff;
+ static final int INTMASK = 0x7fffffff;
static final char[][] converterMaps = new char[7][];
@@ -919,7 +919,11 @@
bbuffer.position(12);
bbuffer.get(is32);
- nGroups = bbuffer.getInt();
+ nGroups = bbuffer.getInt() & INTMASK;
+ // A map group record is three uint32's making for 12 bytes total
+ if (bbuffer.remaining() < (12 * (long)nGroups)) {
+ throw new RuntimeException("Format 8 table exceeded");
+ }
startCharCode = new int[nGroups];
endCharCode = new int[nGroups];
startGlyphID = new int[nGroups];
@@ -947,9 +951,13 @@
CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
+ bbuffer.position(offset+12);
firstCode = bbuffer.getInt() & INTMASK;
entryCount = bbuffer.getInt() & INTMASK;
- bbuffer.position(offset+20);
+ // each glyph is a uint16, so 2 bytes per value.
+ if (bbuffer.remaining() < (2 * (long)entryCount)) {
+ throw new RuntimeException("Format 10 table exceeded");
+ }
CharBuffer buffer = bbuffer.asCharBuffer();
glyphIdArray = new char[entryCount];
for (int i=0; i< entryCount; i++) {
@@ -989,11 +997,15 @@
throw new RuntimeException("xlat array for cmap fmt=12");
}
- numGroups = buffer.getInt(offset+12);
+ buffer.position(offset+12);
+ numGroups = buffer.getInt() & INTMASK;
+ // A map group record is three uint32's making for 12 bytes total
+ if (buffer.remaining() < (12 * (long)numGroups)) {
+ throw new RuntimeException("Format 12 table exceeded");
+ }
startCharCode = new long[numGroups];
endCharCode = new long[numGroups];
startGlyphID = new int[numGroups];
- buffer.position(offset+16);
buffer = buffer.slice();
IntBuffer ibuffer = buffer.asIntBuffer();
for (int i=0; i<numGroups; i++) {
@@ -1110,7 +1122,13 @@
char[][] glyphID;
UVS(ByteBuffer buffer, int offset) {
- numSelectors = buffer.getInt(offset+6);
+ buffer.position(offset+6);
+ numSelectors = buffer.getInt() & INTMASK;
+ // A variation selector record is one 3 byte int + two int32's
+ // making for 11 bytes per record.
+ if (buffer.remaining() < (11 * (long)numSelectors)) {
+ throw new RuntimeException("Variations exceed buffer");
+ }
selector = new int[numSelectors];
numUVSMapping = new int[numSelectors];
unicodeValue = new int[numSelectors][];
@@ -1131,6 +1149,11 @@
} else if (tableOffset > 0) {
buffer.position(offset+tableOffset);
numUVSMapping[i] = buffer.getInt() & INTMASK;
+ // a UVS mapping record is one 3 byte int + uint16
+ // making for 5 bytes per record.
+ if (buffer.remaining() < (5 * (long)numUVSMapping[i])) {
+ throw new RuntimeException("Variations exceed buffer");
+ }
unicodeValue[i] = new int[numUVSMapping[i]];
glyphID[i] = new char[numUVSMapping[i]];
--- a/src/java.desktop/share/classes/sun/font/FileFont.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/sun/font/FileFont.java Wed Oct 16 11:23:46 2019 +0200
@@ -172,7 +172,7 @@
}
}
if (scaler != null) {
- scaler.dispose();
+ scaler.disposeScaler();
}
scaler = FontScaler.getNullScaler();
}
--- a/src/java.desktop/share/classes/sun/font/FontScaler.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/sun/font/FontScaler.java Wed Oct 16 11:23:46 2019 +0200
@@ -173,6 +173,12 @@
scaler context objects! */
public void dispose() {}
+ /**
+ * Used when the native resources held by the scaler need
+ * to be released before the 2D disposer runs.
+ */
+ public void disposeScaler() {}
+
/* At the moment these 3 methods are needed for Type1 fonts only.
* For Truetype fonts we extract required info outside of scaler
* on java layer.
--- a/src/java.desktop/share/classes/sun/font/FreetypeFontScaler.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/sun/font/FreetypeFontScaler.java Wed Oct 16 11:23:46 2019 +0200
@@ -163,6 +163,9 @@
.getNullScaler().getGlyphVectorOutline(0L, glyphs, numGlyphs, x, y);
}
+ /* This method should not be called directly, in case
+ * it is being invoked from a thread with a native context.
+ */
public synchronized void dispose() {
if (nativeScaler != 0L) {
disposeNativeScaler(font.get(), nativeScaler);
@@ -170,6 +173,21 @@
}
}
+ public synchronized void disposeScaler() {
+ if (nativeScaler != 0L) {
+ /*
+ * The current thread may be calling this method from the context
+ * of a JNI up-call. It will hold the native lock from the
+ * original down-call so can directly enter dispose and free
+ * the resources. So we need to schedule the disposal to happen
+ * only once we've returned from native. So by running the dispose
+ * on another thread which does nothing except that disposal we
+ * are sure that this is safe.
+ */
+ new Thread(null, () -> dispose(), "free scaler", 0, false).start();
+ }
+ }
+
synchronized int getNumGlyphs() throws FontScalerException {
if (nativeScaler != 0L) {
return getNumGlyphsNative(nativeScaler);
@@ -206,7 +224,7 @@
return getUnitsPerEMNative(nativeScaler);
}
- long createScalerContext(double[] matrix,
+ synchronized long createScalerContext(double[] matrix,
int aa, int fm, float boldness, float italic,
boolean disableHinting) {
if (nativeScaler != 0L) {
@@ -236,7 +254,7 @@
private native GeneralPath getGlyphVectorOutlineNative(Font2D font,
long pScalerContext, long pScaler,
int[] glyphs, int numGlyphs, float x, float y);
- native Point2D.Float getGlyphPointNative(Font2D font,
+ private native Point2D.Float getGlyphPointNative(Font2D font,
long pScalerContext, long pScaler, int glyphCode, int ptNumber);
private native void disposeNativeScaler(Font2D font2D, long pScaler);
@@ -247,7 +265,7 @@
private native long getUnitsPerEMNative(long pScaler);
- native long createScalerContextNative(long pScaler, double[] matrix,
+ private native long createScalerContextNative(long pScaler, double[] matrix,
int aa, int fm, float boldness, float italic);
/* Freetype scaler context does not contain any pointers that
--- a/src/java.desktop/share/classes/sun/font/GlyphList.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/sun/font/GlyphList.java Wed Oct 16 11:23:46 2019 +0200
@@ -303,6 +303,14 @@
*/
public void setGlyphIndex(int i) {
glyphindex = i;
+ if (images[i] == 0L) {
+ metrics[0] = (int)gposx;
+ metrics[1] = (int)gposy;
+ metrics[2] = 0;
+ metrics[3] = 0;
+ metrics[4] = 0;
+ return;
+ }
float gx =
StrikeCache.unsafe.getFloat(images[i]+StrikeCache.topLeftXOffset);
float gy =
@@ -341,6 +349,9 @@
graybits = new byte[len];
}
}
+ if (images[glyphindex] == 0L) {
+ return graybits;
+ }
long pixelDataAddress =
StrikeCache.unsafe.getAddress(images[glyphindex] +
StrikeCache.pixelDataOffset);
@@ -448,6 +459,9 @@
char gw, gh;
float gx, gy, gx0, gy0, gx1, gy1;
for (int i=0; i<len; i++) {
+ if (images[i] == 0L) {
+ continue;
+ }
gx = StrikeCache.unsafe.getFloat(images[i]+xOffset);
gy = StrikeCache.unsafe.getFloat(images[i]+yOffset);
gw = StrikeCache.unsafe.getChar(images[i]+wOffset);
--- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Wed Oct 16 11:23:46 2019 +0200
@@ -3021,7 +3021,8 @@
if (data == null) {
throw new NullPointerException("char data is null");
}
- if (offset < 0 || length < 0 || offset + length > data.length) {
+ if (offset < 0 || length < 0 || offset + length < length ||
+ offset + length > data.length) {
throw new ArrayIndexOutOfBoundsException("bad offset/length");
}
if (font.hasLayoutAttributes()) {
@@ -3053,7 +3054,8 @@
if (data == null) {
throw new NullPointerException("byte data is null");
}
- if (offset < 0 || length < 0 || offset + length > data.length) {
+ if (offset < 0 || length < 0 || offset + length < length ||
+ offset + length > data.length) {
throw new ArrayIndexOutOfBoundsException("bad offset/length");
}
/* Byte data is interpreted as 8-bit ASCII. Re-use drawChars loops */
--- a/src/java.desktop/share/native/common/java2d/opengl/OGLBlitLoops.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/native/common/java2d/opengl/OGLBlitLoops.c Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, 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
@@ -208,21 +208,22 @@
j2d_glPixelZoom(scalex, -scaley);
+ GLvoid *pSrc = PtrCoord(srcInfo->rasBase, sx1, srcInfo->pixelStride,
+ sy1, srcInfo->scanStride);
+
// in case pixel stride is not a multiple of scanline stride the copy
// has to be done line by line (see 6207877)
if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
jint width = sx2-sx1;
jint height = sy2-sy1;
- GLvoid *pSrc = srcInfo->rasBase;
-
while (height > 0) {
j2d_glDrawPixels(width, 1, pf->format, pf->type, pSrc);
- j2d_glBitmap(0, 0, 0, 0, (GLfloat)0, (GLfloat)-1, NULL);
+ j2d_glBitmap(0, 0, 0, 0, (GLfloat)0, (GLfloat)-scaley, NULL);
pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
height--;
}
} else {
- j2d_glDrawPixels(sx2-sx1, sy2-sy1, pf->format, pf->type, srcInfo->rasBase);
+ j2d_glDrawPixels(sx2-sx1, sy2-sy1, pf->format, pf->type, pSrc);
}
j2d_glPixelZoom(1.0, 1.0);
@@ -317,12 +318,11 @@
ty2 = ((GLdouble)sh) / th;
if (swsurface) {
+ GLvoid *pSrc = PtrCoord(srcInfo->rasBase,
+ sx, srcInfo->pixelStride,
+ sy, srcInfo->scanStride);
if (slowPath) {
jint tmph = sh;
- GLvoid *pSrc = PtrCoord(srcInfo->rasBase,
- sx, srcInfo->pixelStride,
- sy, srcInfo->scanStride);
-
while (tmph > 0) {
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
0, sh - tmph, sw, 1,
@@ -332,16 +332,10 @@
tmph--;
}
} else {
- j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
- j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
-
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, sw, sh,
pf->format, pf->type,
- srcInfo->rasBase);
-
- j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ pSrc);
}
// the texture image is "right side up", so we align the
@@ -638,8 +632,9 @@
J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f",
dx1, dy1, dx2, dy2);
- j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx1);
- j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy1);
+ // Note: we will calculate x/y positions in the raster manually
+ j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH,
srcInfo.scanStride / srcInfo.pixelStride);
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, pf.alignment);
@@ -696,8 +691,6 @@
}
}
- j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
@@ -717,8 +710,8 @@
juint step = 0;
// vertical flip and convert argbpre to argb if necessary
for (; i < h / 2; ++i) {
- juint *r1 = PtrAddBytes(pDst, (i * scanStride));
- juint *r2 = PtrAddBytes(pDst, (h - i - 1) * scanStride);
+ juint *r1 = PtrPixelsRow(pDst, i, scanStride);
+ juint *r2 = PtrPixelsRow(pDst, h - i - 1, scanStride);
if (tempRow) {
// fast path
memcpy(tempRow, r1, clippedStride);
@@ -740,7 +733,7 @@
}
// convert the middle line if necessary
if (convert && h % 2) {
- juint *r1 = PtrAddBytes(pDst, (i * scanStride));
+ juint *r1 = PtrPixelsRow(pDst, i, scanStride);
for (step = 0; step < w; ++step) {
LoadIntArgbPreTo1IntArgb(r1, 0, step, r1[step]);
}
@@ -813,7 +806,7 @@
height = srcInfo.bounds.y2 - srcInfo.bounds.y1;
pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride);
- pDst = PtrAddBytes(pDst, dsty * dstInfo.scanStride);
+ pDst = PtrPixelsRow(pDst, dsty, dstInfo.scanStride);
j2d_glPixelStorei(GL_PACK_ROW_LENGTH,
dstInfo.scanStride / dstInfo.pixelStride);
--- a/src/java.desktop/share/native/libawt/java2d/loops/GraphicsPrimitiveMgr.h Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/native/libawt/java2d/loops/GraphicsPrimitiveMgr.h Wed Oct 16 11:23:46 2019 +0200
@@ -490,6 +490,8 @@
#define PtrCoord(p, x, xinc, y, yinc) PtrAddBytes(p, \
((ptrdiff_t)(y))*(yinc) + \
((ptrdiff_t)(x))*(xinc))
+#define PtrPixelsRow(p, y, scanStride) PtrAddBytes(p, \
+ ((intptr_t) (y)) * (scanStride))
/*
* The function to call with an array of NativePrimitive structures
--- a/src/java.desktop/share/native/libawt/java2d/loops/LoopMacros.h Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/native/libawt/java2d/loops/LoopMacros.h Wed Oct 16 11:23:46 2019 +0200
@@ -137,7 +137,7 @@
do { \
juint w = WIDTH; \
jint tmpsxloc = SXLOC; \
- SRCPTR = PtrAddBytes(SRCBASE, ((SYLOC >> SHIFT) * srcScan)); \
+ SRCPTR = PtrPixelsRow(SRCBASE, (SYLOC >> SHIFT), srcScan); \
Init ## DSTTYPE ## StoreVarsX(DSTPREFIX, DSTINFO); \
do { \
jint XVAR = (tmpsxloc >> SHIFT); \
@@ -2067,7 +2067,7 @@
\
Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \
while (pRGB < pEnd) { \
- SRC ## DataType *pRow = PtrAddBytes(pBase, WholeOfLong(ylong) * scan); \
+ SRC ## DataType *pRow = PtrPixelsRow(pBase, WholeOfLong(ylong), scan); \
Copy ## SRC ## ToIntArgbPre(pRGB, 0, \
SrcRead, pRow, WholeOfLong(xlong)); \
pRGB++; \
@@ -2115,7 +2115,7 @@
ydelta &= scan; \
\
xwhole += cx; \
- pRow = PtrAddBytes(pSrcInfo->rasBase, (ywhole + cy) * scan); \
+ pRow = PtrPixelsRow(pSrcInfo->rasBase, ywhole + cy, scan); \
Copy ## SRC ## ToIntArgbPre(pRGB, 0, SrcRead, pRow, xwhole); \
Copy ## SRC ## ToIntArgbPre(pRGB, 1, SrcRead, pRow, xwhole+xdelta); \
pRow = PtrAddBytes(pRow, ydelta); \
@@ -2173,7 +2173,7 @@
ydelta1 += (isneg & -scan); \
\
xwhole += cx; \
- pRow = PtrAddBytes(pSrcInfo->rasBase, (ywhole + cy) * scan); \
+ pRow = PtrPixelsRow(pSrcInfo->rasBase, ywhole + cy, scan); \
pRow = PtrAddBytes(pRow, ydelta0); \
Copy ## SRC ## ToIntArgbPre(pRGB, 0, SrcRead, pRow, xwhole+xdelta0); \
Copy ## SRC ## ToIntArgbPre(pRGB, 1, SrcRead, pRow, xwhole ); \
--- a/src/java.desktop/share/native/libfontmanager/DrawGlyphList.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/native/libfontmanager/DrawGlyphList.c Wed Oct 16 11:23:46 2019 +0200
@@ -532,6 +532,12 @@
*/
if (subPixPos && len > 0) {
ginfo = (GlyphInfo*)imagePtrs[0];
+ if (ginfo == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, glyphImages,
+ imagePtrs, JNI_ABORT);
+ free(gbv);
+ return (GlyphBlitVector*)NULL;
+ }
/* rowBytes==width tests if its a B&W or LCD glyph */
if (ginfo->width == ginfo->rowBytes) {
subPixPos = JNI_FALSE;
@@ -561,6 +567,12 @@
jfloat px, py;
ginfo = (GlyphInfo*)imagePtrs[g];
+ if (ginfo == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, glyphImages,
+ imagePtrs, JNI_ABORT);
+ free(gbv);
+ return (GlyphBlitVector*)NULL;
+ }
gbv->glyphs[g].glyphInfo = ginfo;
gbv->glyphs[g].pixels = ginfo->image;
gbv->glyphs[g].width = ginfo->width;
@@ -636,6 +648,12 @@
} else {
for (g=0; g<len; g++) {
ginfo = (GlyphInfo*)imagePtrs[g];
+ if (ginfo == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, glyphImages,
+ imagePtrs, JNI_ABORT);
+ free(gbv);
+ return (GlyphBlitVector*)NULL;
+ }
gbv->glyphs[g].glyphInfo = ginfo;
gbv->glyphs[g].pixels = ginfo->image;
gbv->glyphs[g].width = ginfo->width;
--- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c Wed Oct 16 11:23:46 2019 +0200
@@ -154,7 +154,31 @@
jobject bBuffer;
int bread = 0;
- if (numBytes == 0) return 0;
+ /* A call with numBytes == 0 is a seek. It should return 0 if the
+ * seek position is within the file and non-zero otherwise.
+ * For all other cases, ie numBytes !=0, return the number of bytes
+ * actually read. This applies to truncated reads and also failed reads.
+ */
+
+ if (numBytes == 0) {
+ if (offset > scalerInfo->fileSize) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+
+ if (offset + numBytes < offset) {
+ return 0; // ft should not do this, but just in case.
+ }
+
+ if (offset >= scalerInfo->fileSize) {
+ return 0;
+ }
+
+ if (offset + numBytes > scalerInfo->fileSize) {
+ numBytes = scalerInfo->fileSize - offset;
+ }
/* Large reads will bypass the cache and data copying */
if (numBytes > FILEDATACACHESIZE) {
@@ -164,7 +188,11 @@
scalerInfo->font2D,
sunFontIDs.ttReadBlockMID,
bBuffer, offset, numBytes);
- return bread;
+ if (bread < 0) {
+ return 0;
+ } else {
+ return bread;
+ }
} else {
/* We probably hit bug 4845371. For reasons that
* are currently unclear, the call stacks after the initial
@@ -179,9 +207,18 @@
(*env)->CallObjectMethod(env, scalerInfo->font2D,
sunFontIDs.ttReadBytesMID,
offset, numBytes);
- (*env)->GetByteArrayRegion(env, byteArray,
- 0, numBytes, (jbyte*)destBuffer);
- return numBytes;
+ /* If there's an OutofMemoryError then byteArray will be null */
+ if (byteArray == NULL) {
+ return 0;
+ } else {
+ jsize len = (*env)->GetArrayLength(env, byteArray);
+ if (len < numBytes) {
+ numBytes = len; // don't get more bytes than there are ..
+ }
+ (*env)->GetByteArrayRegion(env, byteArray,
+ 0, numBytes, (jbyte*)destBuffer);
+ return numBytes;
+ }
}
} /* Do we have a cache hit? */
else if (scalerInfo->fontDataOffset <= offset &&
@@ -203,6 +240,11 @@
sunFontIDs.ttReadBlockMID,
bBuffer, offset,
scalerInfo->fontDataLength);
+ if (bread <= 0) {
+ return 0;
+ } else if (bread < numBytes) {
+ numBytes = bread;
+ }
memcpy(destBuffer, scalerInfo->fontData, numBytes);
return numBytes;
}
@@ -593,16 +635,17 @@
to avoid unnecesary work with bitmaps. */
GlyphInfo *info;
- jfloat advance;
+ jfloat advance = 0.0f;
jlong image;
image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
env, scaler, font2D, pScalerContext, pScaler, glyphCode);
info = (GlyphInfo*) jlong_to_ptr(image);
- advance = info->advanceX;
-
- free(info);
+ if (info != NULL) {
+ advance = info->advanceX;
+ free(info);
+ }
return advance;
}
@@ -740,6 +783,13 @@
}
+/* JDK does not use glyph images for fonts with a
+ * pixel size > 100 (see THRESHOLD in OutlineTextRenderer.java)
+ * so if the glyph bitmap image dimension is > 1024 pixels,
+ * something is up.
+ */
+#define MAX_GLYPH_DIM 1024
+
/*
* Class: sun_font_FreetypeFontScaler
* Method: getGlyphImageNative
@@ -813,6 +863,14 @@
/* generate bitmap if it is not done yet
e.g. if algorithmic styling is performed and style was added to outline */
if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+ FT_BBox bbox;
+ FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
+ int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
+ int h = (int)((bbox.yMax>>6)-(bbox.yMin>>6));
+ if (w > MAX_GLYPH_DIM || h > MAX_GLYPH_DIM) {
+ glyphInfo = getNullGlyphImage();
+ return ptr_to_jlong(glyphInfo);
+ }
error = FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target));
if (error != 0) {
return ptr_to_jlong(getNullGlyphImage());
@@ -821,6 +879,11 @@
width = (UInt16) ftglyph->bitmap.width;
height = (UInt16) ftglyph->bitmap.rows;
+ if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
+ glyphInfo = getNullGlyphImage();
+ return ptr_to_jlong(glyphInfo);
+ }
+
imageSize = width*height;
glyphInfo = (GlyphInfo*) malloc(sizeof(GlyphInfo) + imageSize);
--- a/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc Wed Oct 16 11:23:46 2019 +0200
@@ -351,6 +351,9 @@
}
length = env->GetArrayLength(tableBytes);
buffer = calloc(length, sizeof(jbyte));
+ if (buffer == NULL) {
+ return NULL;
+ }
env->GetByteArrayRegion(tableBytes, 0, length, (jbyte*)buffer);
return hb_blob_create((const char *)buffer, length,
--- a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java Wed Oct 16 11:23:46 2019 +0200
@@ -25,7 +25,6 @@
package sun.font;
-import java.awt.Font;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -45,11 +44,9 @@
import sun.awt.FontDescriptor;
import sun.awt.SunToolkit;
import sun.font.CompositeFontDescriptor;
-import sun.font.FontManager;
import sun.font.FontConfigManager.FontConfigInfo;
import sun.font.FontConfigManager.FcCompFont;
import sun.font.FontConfigManager.FontConfigFont;
-import sun.java2d.SunGraphicsEnvironment;
import sun.util.logging.PlatformLogger;
public class FcFontConfiguration extends FontConfiguration {
@@ -289,12 +286,10 @@
/**
* Gets the OS version string from a Linux release-specific file.
*/
- private String getVersionString(File f){
- try {
- Scanner sc = new Scanner(f);
+ private String getVersionString(File f) {
+ try (Scanner sc = new Scanner(f)) {
return sc.findInLine("(\\d)+((\\.)(\\d)+)*");
- }
- catch (Exception e){
+ } catch (Exception e) {
}
return null;
}
@@ -429,23 +424,26 @@
private void readFcInfo() {
File fcFile = getFcInfoFile();
if (!fcFile.exists()) {
+ if (FontUtilities.debugFonts()) {
+ warning("fontconfig info file " + fcFile.toString() + " does not exist");
+ }
return;
}
Properties props = new Properties();
- FcFontManager fm = (FcFontManager) fontManager;
- FontConfigManager fcm = fm.getFontConfigManager();
- try {
- FileInputStream fis = new FileInputStream(fcFile);
+ try (FileInputStream fis = new FileInputStream(fcFile)) {
props.load(fis);
- fis.close();
} catch (IOException e) {
if (FontUtilities.debugFonts()) {
- warning("IOException reading from "+fcFile.toString());
+ warning("IOException (" + e.getCause() + ") reading from " + fcFile.toString());
}
return;
}
String version = (String)props.get("version");
if (version == null || !version.equals(fileVersion)) {
+ if (FontUtilities.debugFonts()) {
+ warning("fontconfig info file version mismatch (found: " + version +
+ ", expected: " + fileVersion + ")");
+ }
return;
}
@@ -458,6 +456,9 @@
fcVersion = Integer.parseInt(fcVersionStr);
if (fcVersion != 0 &&
fcVersion != FontConfigManager.getFontConfigVersion()) {
+ if (FontUtilities.debugFonts()) {
+ warning("new, different fontconfig detected");
+ }
return;
}
} catch (Exception e) {
@@ -480,6 +481,9 @@
}
File dirFile = new File(dir);
if (dirFile.exists() && dirFile.lastModified() > lastModified) {
+ if (FontUtilities.debugFonts()) {
+ warning("out of date cache directories detected");
+ }
return;
}
cacheDirIndex++;
@@ -503,6 +507,9 @@
String lenStr = (String)props.get(key+".length");
int nfonts = Integer.parseInt(lenStr);
if (nfonts <= 0) {
+ if (FontUtilities.debugFonts()) {
+ warning("bad non-positive .length entry in fontconfig file " + fcFile.toString());
+ }
return; // bad file
}
fci[index].allFonts = new FontConfigFont[nfonts];
@@ -514,6 +521,9 @@
fkey = key+"."+f+".file";
String file = (String)props.get(fkey);
if (file == null) {
+ if (FontUtilities.debugFonts()) {
+ warning("missing file value for key " + fkey + " in fontconfig file " + fcFile.toString());
+ }
return; // bad file
}
fci[index].allFonts[f].fontFile = file;
@@ -528,6 +538,11 @@
warning(t.toString());
}
}
+
+ if (FontUtilities.debugFonts()) {
+ PlatformLogger logger = FontUtilities.getLogger();
+ logger.info("successfully parsed the fontconfig file at " + fcFile.toString());
+ }
}
private static void warning(String msg) {
--- a/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java Wed Oct 16 11:23:46 2019 +0200
@@ -114,6 +114,9 @@
for (int i = 0; i < glyphList.getNumGlyphs(); i++) {
XRGlyphCacheEntry glyph;
+ if (imgPtrs[i] == 0L) {
+ continue;
+ }
// Find uncached glyphs and queue them for upload
if ((glyph = getEntryForPointer(imgPtrs[i])) == null) {
glyph = new XRGlyphCacheEntry(imgPtrs[i], glyphList);
--- a/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java Wed Oct 16 11:23:46 2019 +0200
@@ -88,6 +88,9 @@
for (int i = 0; i < gl.getNumGlyphs(); i++) {
gl.setGlyphIndex(i);
XRGlyphCacheEntry cacheEntry = cachedGlyphs[i];
+ if (cacheEntry == null) {
+ continue;
+ }
eltList.getGlyphs().addInt(cacheEntry.getGlyphID());
int glyphSet = cacheEntry.getGlyphSet();
--- a/src/java.desktop/unix/native/common/awt/X11Color.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/native/common/awt/X11Color.c Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, 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
@@ -336,19 +336,6 @@
return awt_color_match(r, g, b, awt_data);
}
-
-void
-awt_allocate_systemcolors(XColor *colorsPtr, int num_pixels, AwtGraphicsConfigDataPtr awtData) {
- int i;
- int r, g, b, pixel;
-
- for (i=0; i < num_pixels; i++) {
- r = colorsPtr[i].red >> 8;
- g = colorsPtr[i].green >> 8;
- b = colorsPtr[i].blue >> 8;
- pixel = alloc_col(awt_display, awtData->awt_cmap, r, g, b, -1, awtData);
- }
-}
#endif /* !HEADLESS */
void
@@ -1276,12 +1263,6 @@
extern jfieldID colorValueID;
#ifndef HEADLESS
-int awtJNI_GetColor(JNIEnv *env,jobject this)
-{
- /* REMIND: should not be defaultConfig. */
- return awtJNI_GetColorForVis (env, this, getDefaultConfig(DefaultScreen(awt_display)));
-}
-
int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr awt_data)
{
int col;
--- a/src/java.desktop/unix/native/common/awt/awt_Font.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/native/common/awt/awt_Font.c Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, 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
@@ -23,51 +23,10 @@
* questions.
*/
-#ifndef HEADLESS
-
-#include "awt_p.h"
-#include <string.h>
-#include "java_awt_Component.h"
#include "java_awt_Font.h"
-#include "java_awt_FontMetrics.h"
-#include "sun_awt_X11GraphicsEnvironment.h"
-
-#include "awt_Font.h"
-
-#include "java_awt_Dimension.h"
-#include "Disposer.h"
-#endif /* !HEADLESS */
-#include <jni.h>
-#ifndef HEADLESS
-#include <jni_util.h>
-
-#define defaultXLFD "-*-helvetica-*-*-*-*-12-*-*-*-*-*-iso8859-1"
-
-struct FontIDs fontIDs;
-struct PlatformFontIDs platformFontIDs;
+#include "sun_awt_FontDescriptor.h"
+#include "sun_awt_PlatformFont.h"
-static void pDataDisposeMethod(JNIEnv *env, jlong pData);
-
-/* #define FONT_DEBUG 2 */
-/* 1- print failures, 2- print all, 3- terminate on failure */
-#if FONT_DEBUG
-static XFontStruct *XLoadQueryFontX(Display *display, char *name)
-{
- XFontStruct *result = NULL;
- result = XLoadQueryFont(display, name);
-#if FONT_DEBUG < 2
- if (result == NULL)
-#endif
- fprintf(stderr, "XLoadQueryFont(\"%s\") -> 0x%x.\n", name, result);
-#if FONT_DEBUG >= 3
- if (result == NULL)
- exit(-1);
-#endif
- return result;
-}
-#define XLoadQueryFont XLoadQueryFontX
-#endif
-#endif /* !HEADLESS */
/*
* Class: java_awt_Font
@@ -79,28 +38,9 @@
to initialize the fieldIDs for fields that may be accessed from C */
JNIEXPORT void JNICALL
-Java_java_awt_Font_initIDs
- (JNIEnv *env, jclass cls)
-{
-#ifndef HEADLESS
- CHECK_NULL(fontIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J"));
- CHECK_NULL(fontIDs.style = (*env)->GetFieldID(env, cls, "style", "I"));
- CHECK_NULL(fontIDs.size = (*env)->GetFieldID(env, cls, "size", "I"));
- CHECK_NULL(fontIDs.getPeer = (*env)->GetMethodID(env, cls, "getFontPeer",
- "()Ljava/awt/peer/FontPeer;"));
- CHECK_NULL(fontIDs.getFamily = (*env)->GetMethodID(env, cls, "getFamily_NoClientCode",
- "()Ljava/lang/String;"));
-#endif /* !HEADLESS */
+Java_java_awt_Font_initIDs(JNIEnv *env, jclass cls) {
}
-#ifndef HEADLESS
-/* fieldIDs for FontDescriptor fields that may be accessed from C */
-static struct FontDescriptorIDs {
- jfieldID nativeName;
- jfieldID charsetName;
-} fontDescriptorIDs;
-#endif /* !HEADLESS */
-
/*
* Class: sun_awt_FontDescriptor
* Method: initIDs
@@ -112,15 +52,7 @@
that may be accessed from C */
JNIEXPORT void JNICALL
-Java_sun_awt_FontDescriptor_initIDs
- (JNIEnv *env, jclass cls)
-{
-#ifndef HEADLESS
- CHECK_NULL(fontDescriptorIDs.nativeName =
- (*env)->GetFieldID(env, cls, "nativeName", "Ljava/lang/String;"));
- CHECK_NULL(fontDescriptorIDs.charsetName =
- (*env)->GetFieldID(env, cls, "charsetName", "Ljava/lang/String;"));
-#endif /* !HEADLESS */
+Java_sun_awt_FontDescriptor_initIDs(JNIEnv *env, jclass cls) {
}
/*
@@ -134,354 +66,5 @@
that may be accessed from C */
JNIEXPORT void JNICALL
-Java_sun_awt_PlatformFont_initIDs
- (JNIEnv *env, jclass cls)
-{
-#ifndef HEADLESS
- CHECK_NULL(platformFontIDs.componentFonts =
- (*env)->GetFieldID(env, cls, "componentFonts",
- "[Lsun/awt/FontDescriptor;"));
- CHECK_NULL(platformFontIDs.fontConfig =
- (*env)->GetFieldID(env,cls, "fontConfig",
- "Lsun/awt/FontConfiguration;"));
- CHECK_NULL(platformFontIDs.makeConvertedMultiFontString =
- (*env)->GetMethodID(env, cls, "makeConvertedMultiFontString",
- "(Ljava/lang/String;)[Ljava/lang/Object;"));
- CHECK_NULL(platformFontIDs.makeConvertedMultiFontChars =
- (*env)->GetMethodID(env, cls, "makeConvertedMultiFontChars",
- "([CII)[Ljava/lang/Object;"));
-#endif /* !HEADLESS */
+Java_sun_awt_PlatformFont_initIDs(JNIEnv *env, jclass cls) {
}
-
-#ifndef HEADLESS
-XFontStruct *
-loadFont(Display * display, char *name, int32_t pointSize)
-{
- XFontStruct *f = NULL;
-
- /* try the exact xlfd name in font configuration file */
- f = XLoadQueryFont(display, name);
- if (f != NULL) {
- return f;
- }
-
- /*
- * try nearly font
- *
- * 1. specify FAMILY_NAME, WEIGHT_NAME, SLANT, POINT_SIZE,
- * CHARSET_REGISTRY and CHARSET_ENCODING.
- * 2. change POINT_SIZE to PIXEL_SIZE
- * 3. change FAMILY_NAME to *
- * 4. specify only PIXEL_SIZE and CHARSET_REGISTRY/ENCODING
- * 5. change PIXEL_SIZE +1/-1/+2/-2...+4/-4
- * 6. default font pattern
- */
- {
- /*
- * This code assumes the name contains exactly 14 '-' delimiter.
- * If not use default pattern.
- */
- int32_t i, length, pixelSize;
- Boolean useDefault = FALSE;
-
- char buffer[BUFSIZ], buffer2[BUFSIZ];
- char *family = NULL, *style = NULL, *slant = NULL, *encoding = NULL;
- char *start = NULL, *end = NULL;
-
- if (strlen(name) > BUFSIZ - 1) {
- useDefault = TRUE;
- } else {
- strcpy(buffer, name);
- }
-
-#define NEXT_HYPHEN\
- start = end + 1;\
- end = strchr(start, '-');\
- if (end == NULL) {\
- useDefault = TRUE;\
- break;\
- }\
- *end = '\0'
-
- do {
- end = buffer;
-
- /* skip FOUNDRY */
- NEXT_HYPHEN;
-
- /* set FAMILY_NAME */
- NEXT_HYPHEN;
- family = start;
-
- /* set STYLE_NAME */
- NEXT_HYPHEN;
- style = start;
-
- /* set SLANT */
- NEXT_HYPHEN;
- slant = start;
-
- /* skip SETWIDTH_NAME, ADD_STYLE_NAME, PIXEL_SIZE
- POINT_SIZE, RESOLUTION_X, RESOLUTION_Y, SPACING
- and AVERAGE_WIDTH */
- NEXT_HYPHEN;
- NEXT_HYPHEN;
- NEXT_HYPHEN;
- NEXT_HYPHEN;
- NEXT_HYPHEN;
- NEXT_HYPHEN;
- NEXT_HYPHEN;
- NEXT_HYPHEN;
-
- /* set CHARSET_REGISTRY and CHARSET_ENCODING */
- encoding = end + 1;
- }
- while (0);
-
-#define TRY_LOAD\
- f = XLoadQueryFont(display, buffer2);\
- if (f != NULL) {\
- strcpy(name, buffer2);\
- return f;\
- }
-
- if (!useDefault) {
- char *altstyle = NULL;
-
- /* Regular is the style for TrueType fonts -- Type1, F3 use roman */
- if (strcmp(style, "regular") == 0) {
- altstyle = "roman";
- }
-#if defined(__linux__) || defined(MACOSX)
- if (!strcmp(family, "lucidasans")) {
- family = "lucida";
- }
-#endif
- /* try 1. */
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-%s-%s-%s-*-*-*-%d-*-*-*-*-%s",
- family, style, slant, pointSize, encoding);
- TRY_LOAD;
-
- if (altstyle != NULL) {
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-%s-%s-%s-*-*-*-%d-*-*-*-*-%s",
- family, altstyle, slant, pointSize, encoding);
- TRY_LOAD;
- }
-
- /* search bitmap font */
- pixelSize = pointSize / 10;
-
- /* try 2. */
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
- family, style, slant, pixelSize, encoding);
- TRY_LOAD;
-
- if (altstyle != NULL) {
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
- family, altstyle, slant, pixelSize, encoding);
- TRY_LOAD;
- }
-
- /* try 3 */
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-*-%s-%s-*-*-%d-*-*-*-*-*-%s",
- style, slant, pixelSize, encoding);
- TRY_LOAD;
- if (altstyle != NULL) {
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-*-%s-%s-*-*-%d-*-*-*-*-*-%s",
- altstyle, slant, pixelSize, encoding);
- TRY_LOAD;
- }
-
- /* try 4 */
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-*-*-%s-*-*-%d-*-*-*-*-*-%s",
- slant, pixelSize, encoding);
-
- TRY_LOAD;
-
- /* try 5. */
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-*-*-*-*-*-%d-*-*-*-*-*-%s",
- pixelSize, encoding);
- TRY_LOAD;
-
- /* try 6. */
- for (i = 1; i < 4; i++) {
- if (pixelSize < i)
- break;
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
- family, style, slant, pixelSize + i, encoding);
- TRY_LOAD;
-
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
- family, style, slant, pixelSize - i, encoding);
- TRY_LOAD;
-
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-*-*-*-*-*-%d-*-*-*-*-*-%s",
- pixelSize + i, encoding);
- TRY_LOAD;
-
- jio_snprintf(buffer2, sizeof(buffer2),
- "-*-*-*-*-*-*-%d-*-*-*-*-*-%s",
- pixelSize - i, encoding);
- TRY_LOAD;
- }
- }
- }
-
- strcpy(name, defaultXLFD);
- return XLoadQueryFont(display, defaultXLFD);
-}
-
-/*
- * Hardwired list of mappings for generic font names "Helvetica",
- * "TimesRoman", "Courier", "Dialog", and "DialogInput".
- */
-static char *defaultfontname = "fixed";
-static char *defaultfoundry = "misc";
-static char *anyfoundry = "*";
-static char *anystyle = "*-*";
-static char *isolatin1 = "iso8859-1";
-
-static char *
-Style(int32_t s)
-{
- switch (s) {
- case java_awt_Font_ITALIC:
- return "medium-i";
- case java_awt_Font_BOLD:
- return "bold-r";
- case java_awt_Font_BOLD + java_awt_Font_ITALIC:
- return "bold-i";
- case java_awt_Font_PLAIN:
- default:
- return "medium-r";
- }
-}
-
-static int32_t
-awtJNI_FontName(JNIEnv * env, jstring name, char **foundry, char **facename, char **encoding)
-{
- char *cname = NULL;
-
- if (JNU_IsNull(env, name)) {
- return 0;
- }
- cname = (char *) JNU_GetStringPlatformChars(env, name, NULL);
- if (cname == NULL) {
- (*env)->ExceptionClear(env);
- JNU_ThrowOutOfMemoryError(env, "Could not create font name");
- return 0;
- }
-
- /* additional default font names */
- if (strcmp(cname, "serif") == 0) {
- *foundry = "adobe";
- *facename = "times";
- *encoding = isolatin1;
- } else if (strcmp(cname, "sansserif") == 0) {
- *foundry = "adobe";
- *facename = "helvetica";
- *encoding = isolatin1;
- } else if (strcmp(cname, "monospaced") == 0) {
- *foundry = "adobe";
- *facename = "courier";
- *encoding = isolatin1;
- } else if (strcmp(cname, "helvetica") == 0) {
- *foundry = "adobe";
- *facename = "helvetica";
- *encoding = isolatin1;
- } else if (strcmp(cname, "timesroman") == 0) {
- *foundry = "adobe";
- *facename = "times";
- *encoding = isolatin1;
- } else if (strcmp(cname, "courier") == 0) {
- *foundry = "adobe";
- *facename = "courier";
- *encoding = isolatin1;
- } else if (strcmp(cname, "dialog") == 0) {
- *foundry = "b&h";
- *facename = "lucida";
- *encoding = isolatin1;
- } else if (strcmp(cname, "dialoginput") == 0) {
- *foundry = "b&h";
- *facename = "lucidatypewriter";
- *encoding = isolatin1;
- } else if (strcmp(cname, "zapfdingbats") == 0) {
- *foundry = "itc";
- *facename = "zapfdingbats";
- *encoding = "*-*";
- } else {
-#ifdef DEBUG
- jio_fprintf(stderr, "Unknown font: %s\n", cname);
-#endif
- *foundry = defaultfoundry;
- *facename = defaultfontname;
- *encoding = isolatin1;
- }
-
- if (cname != NULL)
- JNU_ReleaseStringPlatformChars(env, name, (const char *) cname);
-
- return 1;
-}
-
-/*
- * Registered with the 2D disposer to be called after the Font is GC'd.
- */
-static void pDataDisposeMethod(JNIEnv *env, jlong pData)
-{
- struct FontData *fdata = NULL;
- int32_t i = 0;
- Display *display = XDISPLAY;
-
- AWT_LOCK();
- fdata = (struct FontData *)pData;
-
- if (fdata == NULL) {
- AWT_UNLOCK();
- return;
- }
-
- if (fdata->xfs != NULL) {
- XFreeFontSet(display, fdata->xfs);
- }
-
- /* AWT fonts are always "multifonts" and probably have been in
- * all post 1.0 releases, so this test for multi fonts is
- * probably not needed, and the singleton xfont is probably never used.
- */
- if (fdata->charset_num > 0) {
- for (i = 0; i < fdata->charset_num; i++) {
- free((void *)fdata->flist[i].xlfd);
- JNU_ReleaseStringPlatformChars(env, NULL,
- fdata->flist[i].charset_name);
- if (fdata->flist[i].load) {
- XFreeFont(display, fdata->flist[i].xfont);
- }
- }
-
- free((void *)fdata->flist);
-
- /* Don't free fdata->xfont because it is equal to fdata->flist[i].xfont
- for some 'i' */
- } else {
- if (fdata->xfont != NULL) {
- XFreeFont(display, fdata->xfont);
- }
- }
-
- free((void *)fdata);
-
- AWT_UNLOCK();
-}
-#endif /* !HEADLESS */
--- a/src/java.desktop/unix/native/common/awt/awt_Font.h Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni_util.h>
-
-/* fieldIDs for Font fields that may be accessed from C */
-struct FontIDs {
- jfieldID pData;
- jfieldID style;
- jfieldID size;
- jmethodID getPeer;
- jmethodID getFamily;
-};
-
-/* fieldIDs for PlatformFont fields that may be accessed from C */
-struct PlatformFontIDs {
- jfieldID componentFonts;
- jfieldID fontConfig;
- jmethodID makeConvertedMultiFontString;
- jmethodID makeConvertedMultiFontChars;
-};
--- a/src/java.desktop/unix/native/common/awt/awt_p.h Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/native/common/awt/awt_p.h Wed Oct 16 11:23:46 2019 +0200
@@ -30,11 +30,6 @@
#ifndef _AWT_P_H_
#define _AWT_P_H_
-/* turn on to do event filtering */
-#define NEW_EVENT_MODEL
-/* turn on to only filter keyboard events */
-#define KEYBOARD_ONLY_EVENTS
-
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -58,9 +53,6 @@
#endif
#endif /* !HEADLESS */
-#define RepaintPending_NONE 0
-#define RepaintPending_REPAINT (1 << 0)
-#define RepaintPending_EXPOSE (1 << 1)
#define LOOKUPSIZE 32
#ifndef HEADLESS
@@ -101,24 +93,6 @@
typedef AwtScreenData* AwtScreenDataPtr;
-#define W_GRAVITY_INITIALIZED 1
-#define W_IS_EMBEDDED 2
-
-typedef struct awtFontList {
- char *xlfd;
- int index_length;
- int load;
- char *charset_name;
- XFontStruct *xfont;
-} awtFontList;
-
-struct FontData {
- int charset_num;
- awtFontList *flist;
- XFontSet xfs; /* for TextField & TextArea */
- XFontStruct *xfont; /* Latin1 font */
-};
-
extern AwtGraphicsConfigDataPtr getDefaultConfig(int screen);
extern AwtScreenDataPtr getScreenData(int screen);
#endif /* !HEADLESS */
@@ -127,13 +101,10 @@
#define ZALLOC(T) ((struct T *)calloc(1, sizeof(struct T)))
#ifndef HEADLESS
-#define XDISPLAY awt_display;
extern int awt_allocate_colors(AwtGraphicsConfigDataPtr);
-extern void awt_allocate_systemcolors(XColor *, int, AwtGraphicsConfigDataPtr);
extern void awt_allocate_systemrgbcolors(jint *, int, AwtGraphicsConfigDataPtr);
-extern int awtJNI_GetColor(JNIEnv *, jobject);
extern int awtJNI_GetColorForVis (JNIEnv *, jobject, AwtGraphicsConfigDataPtr);
extern jobject awtJNI_GetColorModel(JNIEnv *, AwtGraphicsConfigDataPtr);
extern void awtJNI_CreateColorData (JNIEnv *, AwtGraphicsConfigDataPtr, int lock);
--- a/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c Wed Oct 16 11:23:46 2019 +0200
@@ -273,6 +273,7 @@
unsigned int imageSize;
JNIEnv *env;
+
FONT_AWT_LOCK();
/* XTextExtents16(xFont, xChar, 1, &direction, &ascent, &descent, &xcs); */
XQueryTextExtents16(awt_display,xFont->fid, xChar, 1,
@@ -280,8 +281,11 @@
width = xcs.rbearing - xcs.lbearing;
height = xcs.ascent+xcs.descent;
imageSize = width*height;
-
glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize);
+ if (glyphInfo == NULL) {
+ AWT_UNLOCK();
+ return (jlong)(uintptr_t)NULL;
+ }
glyphInfo->cellInfo = NULL;
glyphInfo->width = width;
glyphInfo->height = height;
--- a/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -39,7 +39,6 @@
#include "awt_p.h"
#include "awt_Component.h"
#include "awt_MenuComponent.h"
-#include "awt_Font.h"
#include "awt_util.h"
#include "sun_awt_X11_XToolkit.h"
--- a/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -1092,7 +1092,9 @@
{
#ifndef PtrAddBytes
#define PtrAddBytes(p, b) ((void *) (((intptr_t) (p)) + (b)))
-#define PtrCoord(p, x, xinc, y, yinc) PtrAddBytes(p, (y)*(yinc) + (x)*(xinc))
+#define PtrCoord(p, x, xinc, y, yinc) PtrAddBytes(p, \
+ ((ptrdiff_t)(y))*(yinc) + \
+ ((ptrdiff_t)(x))*(xinc))
#endif // PtrAddBytes
HRESULT res = S_OK;
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, 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
@@ -51,6 +51,7 @@
/**
* Whether links were encountered.
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Object followingLink = null;
/**
@@ -71,6 +72,7 @@
* The last resolved context. Used to set the "AltNameCtx" in a
* CannotProceedException.
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Context resolvedContext = null;
/**
--- a/src/java.naming/share/classes/javax/naming/Binding.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/javax/naming/Binding.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, 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
@@ -54,6 +54,7 @@
* @see #getObject
* @see #setObject
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private Object boundObj;
/**
--- a/src/java.naming/share/classes/javax/naming/CannotProceedException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/javax/naming/CannotProceedException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2004, 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
@@ -127,6 +127,7 @@
* @see #altName
* @see javax.naming.spi.ObjectFactory#getObjectInstance
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Context altNameCtx = null;
/**
--- a/src/java.naming/share/classes/javax/naming/LinkException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/javax/naming/LinkException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2004, 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
@@ -85,6 +85,7 @@
* @see #getLinkResolvedObj
* @see #setLinkResolvedObj
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Object linkResolvedObj;
/**
--- a/src/java.naming/share/classes/javax/naming/NamingException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/javax/naming/NamingException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2003, 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
@@ -79,6 +79,7 @@
* @see #getResolvedObj
* @see #setResolvedObj
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Object resolvedObj;
/**
* Contains the remaining name that has not been resolved yet.
--- a/src/java.naming/share/classes/javax/naming/event/NamingEvent.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/javax/naming/event/NamingEvent.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2000, 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
@@ -122,6 +122,7 @@
* Contains information about the change that generated this event.
* @serial
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Object changeInfo;
/**
--- a/src/java.naming/share/classes/javax/naming/spi/ResolveResult.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.naming/share/classes/javax/naming/spi/ResolveResult.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2004, 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
@@ -50,6 +50,7 @@
* Constructors should always initialize this.
* @serial
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
protected Object resolvedObj;
/**
* Field containing the remaining name yet to be resolved.
--- a/src/java.rmi/share/classes/java/rmi/activation/ActivationGroup.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/java/rmi/activation/ActivationGroup.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, 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
@@ -107,6 +107,7 @@
/**
* @serial the group's monitor
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private ActivationMonitor monitor;
/**
--- a/src/java.rmi/share/classes/java/rmi/activation/ActivationGroupID.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/java/rmi/activation/ActivationGroupID.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, 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
@@ -49,6 +49,7 @@
/**
* @serial The group's activation system.
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private ActivationSystem system;
/**
--- a/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -189,12 +189,14 @@
/**
* @serial client-side socket factory (if any)
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private RMIClientSocketFactory csf = null;
/**
* @serial server-side socket factory (if any) to use when
* exporting object
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private RMIServerSocketFactory ssf = null;
/* indicate compatibility with JDK 1.1.x version of class */
--- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java Wed Oct 16 11:23:46 2019 +0200
@@ -27,13 +27,8 @@
package sun.rmi.registry;
import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.AccessException;
-import java.rmi.server.RemoteCall;
-import sun.rmi.transport.Connection;
import sun.rmi.transport.StreamRemoteCall;
-import sun.rmi.transport.tcp.TCPConnection;
/**
* Skeleton to dispatch RegistryImpl methods.
@@ -56,7 +51,7 @@
return operations.clone();
}
- public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
+ public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall remoteCall, int opnum, long hash)
throws java.lang.Exception {
if (opnum < 0) {
if (hash == 7583982177005850366L) {
@@ -78,6 +73,7 @@
}
sun.rmi.registry.RegistryImpl server = (sun.rmi.registry.RegistryImpl) obj;
+ StreamRemoteCall call = (StreamRemoteCall) remoteCall;
switch (opnum) {
case 0: // bind(String, Remote)
{
@@ -90,7 +86,8 @@
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
$param_Remote_2 = (java.rmi.Remote) in.readObject();
- } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
call.releaseInputStream();
@@ -123,7 +120,8 @@
try {
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
- } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
call.releaseInputStream();
@@ -149,7 +147,8 @@
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
$param_Remote_2 = (java.rmi.Remote) in.readObject();
- } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
call.releaseInputStream();
@@ -172,7 +171,8 @@
try {
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
- } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
call.releaseInputStream();
--- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Stub.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Stub.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -24,6 +24,11 @@
*/
package sun.rmi.registry;
+
+import java.io.IOException;
+
+import sun.rmi.transport.StreamRemoteCall;
+
/**
* Stubs to invoke RegistryImpl remote methods.
* Originally generated from RMIC but frozen to match RegistryImpl_Skel.
@@ -57,7 +62,7 @@
public void bind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2)
throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
+ StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 0, interfaceHash);
try {
java.io.ObjectOutput out = call.getOutputStream();
out.writeObject($param_String_1);
@@ -82,15 +87,14 @@
public java.lang.String[] list()
throws java.rmi.AccessException, java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
+ StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 1, interfaceHash);
ref.invoke(call);
java.lang.String[] $result;
try {
java.io.ObjectInput in = call.getInputStream();
$result = (java.lang.String[]) in.readObject();
- } catch (java.io.IOException e) {
- throw new java.rmi.UnmarshalException("error unmarshalling return", e);
- } catch (java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
} finally {
ref.done(call);
@@ -109,7 +113,7 @@
public java.rmi.Remote lookup(java.lang.String $param_String_1)
throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash);
+ StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 2, interfaceHash);
try {
java.io.ObjectOutput out = call.getOutputStream();
out.writeObject($param_String_1);
@@ -121,9 +125,8 @@
try {
java.io.ObjectInput in = call.getInputStream();
$result = (java.rmi.Remote) in.readObject();
- } catch (java.io.IOException e) {
- throw new java.rmi.UnmarshalException("error unmarshalling return", e);
- } catch (java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
} finally {
ref.done(call);
@@ -144,7 +147,7 @@
public void rebind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2)
throws java.rmi.AccessException, java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash);
+ StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 3, interfaceHash);
try {
java.io.ObjectOutput out = call.getOutputStream();
out.writeObject($param_String_1);
@@ -167,7 +170,7 @@
public void unbind(java.lang.String $param_String_1)
throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 4, interfaceHash);
+ StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 4, interfaceHash);
try {
java.io.ObjectOutput out = call.getOutputStream();
out.writeObject($param_String_1);
--- a/src/java.rmi/share/classes/sun/rmi/server/ActivatableServerRef.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/server/ActivatableServerRef.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2003, 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
@@ -38,6 +38,7 @@
*
* @author Ann Wollrath
*/
+@SuppressWarnings("serial") // Externalizable class w/o no-arg c'tor
public class ActivatableServerRef extends UnicastServerRef2 {
private static final long serialVersionUID = 2002967993223003793L;
--- a/src/java.rmi/share/classes/sun/rmi/server/Activation.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/server/Activation.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, 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
@@ -145,9 +145,11 @@
private static boolean debugExec;
/** maps activation id to its respective group id */
+ @SuppressWarnings("serial") // Conditionally serializable
private Map<ActivationID,ActivationGroupID> idTable =
new ConcurrentHashMap<>();
/** maps group id to its GroupEntry groups */
+ @SuppressWarnings("serial") // Conditionally serializable
private Map<ActivationGroupID,GroupEntry> groupTable =
new ConcurrentHashMap<>();
@@ -297,6 +299,7 @@
private static final String NAME = ActivationSystem.class.getName();
private static final long serialVersionUID = 4877330021609408794L;
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private ActivationSystem systemStub = null;
SystemRegistryImpl(int port,
@@ -498,6 +501,7 @@
* with RegistryImpl.checkAccess().
* The kind of access is retained for an exception if one is thrown.
*/
+ @SuppressWarnings("serial") // Externalizable class w/o no-arg c'tor
static class SameHostOnlyServerRef extends UnicastServerRef {
private static final long serialVersionUID = 1234L;
private String accessKind; // an exception message
@@ -873,7 +877,9 @@
ActivationGroupDesc desc = null;
ActivationGroupID groupID = null;
long incarnation = 0;
+ @SuppressWarnings("serial") // Conditionally serializable
Map<ActivationID,ObjectEntry> objects = new HashMap<>();
+ @SuppressWarnings("serial") // Conditionally serializable
Set<ActivationID> restartSet = new HashSet<>();
transient ActivationInstantiator group = null;
--- a/src/java.rmi/share/classes/sun/rmi/server/ActivationGroupImpl.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/server/ActivationGroupImpl.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -69,6 +69,7 @@
new Hashtable<>();
private boolean groupInactive = false;
private final ActivationGroupID groupID;
+ @SuppressWarnings("serial") // Conditionally serializable
private final List<ActivationID> lockedIDs = new ArrayList<>();
/**
--- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Skel.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Skel.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -25,6 +25,8 @@
package sun.rmi.transport;
+import java.io.IOException;
+
/**
* Skeleton to dispatch DGC methods.
* Originally generated by RMIC but frozen to match the stubs.
@@ -43,12 +45,13 @@
return operations.clone();
}
- public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
+ public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall remoteCall, int opnum, long hash)
throws java.lang.Exception {
if (hash != interfaceHash)
throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
sun.rmi.transport.DGCImpl server = (sun.rmi.transport.DGCImpl) obj;
+ StreamRemoteCall call = (StreamRemoteCall) remoteCall;
switch (opnum) {
case 0: // clean(ObjID[], long, VMID, boolean)
{
@@ -62,9 +65,8 @@
$param_long_2 = in.readLong();
$param_VMID_3 = (java.rmi.dgc.VMID) in.readObject();
$param_boolean_4 = in.readBoolean();
- } catch (java.io.IOException e) {
- throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
- } catch (java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
call.releaseInputStream();
@@ -88,9 +90,8 @@
$param_arrayOf_ObjID_1 = (java.rmi.server.ObjID[]) in.readObject();
$param_long_2 = in.readLong();
$param_Lease_3 = (java.rmi.dgc.Lease) in.readObject();
- } catch (java.io.IOException e) {
- throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
- } catch (java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
call.releaseInputStream();
--- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -25,16 +25,17 @@
package sun.rmi.transport;
+import sun.rmi.transport.tcp.TCPConnection;
+
+import java.io.IOException;
import java.io.ObjectInputFilter;
-import java.io.ObjectInputStream;
+import java.rmi.RemoteException;
import java.rmi.dgc.Lease;
import java.rmi.dgc.VMID;
import java.rmi.server.UID;
import java.security.AccessController;
import java.security.PrivilegedAction;
-
-import sun.rmi.server.UnicastRef;
-import sun.rmi.transport.tcp.TCPConnection;
+import java.util.ArrayList;
/**
* Stubs to invoke DGC remote methods.
@@ -72,7 +73,9 @@
public void clean(java.rmi.server.ObjID[] $param_arrayOf_ObjID_1, long $param_long_2, java.rmi.dgc.VMID $param_VMID_3, boolean $param_boolean_4)
throws java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
+ StreamRemoteCall call = (StreamRemoteCall)ref.newCall((java.rmi.server.RemoteObject) this,
+ operations, 0, interfaceHash);
+ call.setObjectInputFilter(DGCImpl_Stub::leaseFilter);
try {
java.io.ObjectOutput out = call.getOutputStream();
out.writeObject($param_arrayOf_ObjID_1);
@@ -97,7 +100,10 @@
public java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[] $param_arrayOf_ObjID_1, long $param_long_2, java.rmi.dgc.Lease $param_Lease_3)
throws java.rmi.RemoteException {
try {
- java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
+ StreamRemoteCall call =
+ (StreamRemoteCall)ref.newCall((java.rmi.server.RemoteObject) this,
+ operations, 1, interfaceHash);
+ call.setObjectInputFilter(DGCImpl_Stub::leaseFilter);
try {
java.io.ObjectOutput out = call.getOutputStream();
out.writeObject($param_arrayOf_ObjID_1);
@@ -108,26 +114,16 @@
}
ref.invoke(call);
java.rmi.dgc.Lease $result;
- Connection connection = ((StreamRemoteCall) call).getConnection();
+ Connection connection = call.getConnection();
try {
java.io.ObjectInput in = call.getInputStream();
-
- if (in instanceof ObjectInputStream) {
- /**
- * Set a filter on the stream for the return value.
- */
- ObjectInputStream ois = (ObjectInputStream) in;
- AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
- ois.setObjectInputFilter(DGCImpl_Stub::leaseFilter);
- return null;
- });
- }
$result = (java.rmi.dgc.Lease) in.readObject();
- } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ } catch (ClassCastException | IOException | ClassNotFoundException e) {
if (connection instanceof TCPConnection) {
// Modified to prevent re-use of the connection after an exception
((TCPConnection) connection).getChannel().free(connection, false);
}
+ call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
} finally {
ref.done(call);
@@ -146,6 +142,11 @@
* ObjectInputFilter to filter DGCClient return value (a Lease).
* The list of acceptable classes is very short and explicit.
* The depth and array sizes are limited.
+ * <p>
+ * The filter must accept normal and exception returns.
+ * A DGC server may throw exceptions that may have a cause
+ * and suppressed exceptions.
+ * Only exceptions in {@code java.base} and {@code java.rmi} are allowed.
*
* @param filterInfo access to class, arrayLength, etc.
* @return {@link ObjectInputFilter.Status#ALLOWED} if allowed,
@@ -172,7 +173,14 @@
}
return (clazz == UID.class ||
clazz == VMID.class ||
- clazz == Lease.class)
+ clazz == Lease.class ||
+ (Throwable.class.isAssignableFrom(clazz) &&
+ (Object.class.getModule() == clazz.getModule() ||
+ RemoteException.class.getModule() == clazz.getModule())) ||
+ clazz == StackTraceElement.class ||
+ clazz == ArrayList.class || // for suppressed exceptions, if any
+ clazz == Object.class ||
+ clazz.getName().equals("java.util.Collections$EmptyList"))
? ObjectInputFilter.Status.ALLOWED
: ObjectInputFilter.Status.REJECTED;
}
--- a/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -29,6 +29,7 @@
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
+import java.io.ObjectInputFilter;
import java.io.ObjectOutput;
import java.io.StreamCorruptedException;
import java.rmi.RemoteException;
@@ -36,6 +37,9 @@
import java.rmi.UnmarshalException;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteCall;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
import sun.rmi.runtime.Log;
import sun.rmi.server.UnicastRef;
import sun.rmi.transport.tcp.TCPEndpoint;
@@ -50,6 +54,7 @@
private ConnectionInputStream in = null;
private ConnectionOutputStream out = null;
private Connection conn;
+ private ObjectInputFilter filter = null;
private boolean resultStarted = false;
private Exception serverException = null;
@@ -123,6 +128,13 @@
}
}
+ public void setObjectInputFilter(ObjectInputFilter filter) {
+ if (in != null) {
+ throw new IllegalStateException("set filter must occur before calling getInputStream");
+ }
+ this.filter = filter;
+ }
+
/**
* Get the InputStream the stub/skeleton should get results/arguments
* from.
@@ -132,6 +144,12 @@
Transport.transportLog.log(Log.VERBOSE, "getting input stream");
in = new ConnectionInputStream(conn.getInputStream());
+ if (filter != null) {
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ in.setObjectInputFilter(filter);
+ return null;
+ });
+ }
}
return in;
}
@@ -251,6 +269,7 @@
try {
ex = in.readObject();
} catch (Exception e) {
+ discardPendingRefs();
throw new UnmarshalException("Error unmarshaling return", e);
}
@@ -259,6 +278,7 @@
if (ex instanceof Exception) {
exceptionReceivedFromServer((Exception) ex);
} else {
+ discardPendingRefs();
throw new UnmarshalException("Return type not Exception");
}
// Exception is thrown before fallthrough can occur
--- a/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c Wed Oct 16 11:23:46 2019 +0200
@@ -247,6 +247,7 @@
int netypes;
jint *etypes = NULL;
+ int proxy_flag = 0;
/* Initialize the Kerberos 5 context */
err = krb5_init_context (&kcontext);
@@ -259,6 +260,48 @@
err = krb5_cc_set_flags (kcontext, ccache, flags); /* turn off OPENCLOSE */
}
+ // First round read. The proxy_impersonator config flag is not supported.
+ // This ccache will not be used if this flag exists.
+ if (!err) {
+ err = krb5_cc_start_seq_get (kcontext, ccache, &cursor);
+ }
+
+ if (!err) {
+ while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) {
+ char *serverName = NULL;
+
+ if (!err) {
+ err = krb5_unparse_name (kcontext, creds.server, &serverName);
+ printiferr (err, "while unparsing server name");
+ }
+
+ if (!err) {
+ if (!strcmp(serverName, "krb5_ccache_conf_data/proxy_impersonator@X-CACHECONF:")) {
+ proxy_flag = 1;
+ }
+ }
+
+ if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); }
+
+ krb5_free_cred_contents (kcontext, &creds);
+
+ if (proxy_flag) break;
+ }
+
+ if (err == KRB5_CC_END) { err = 0; }
+ printiferr (err, "while retrieving a ticket");
+ }
+
+ if (!err) {
+ err = krb5_cc_end_seq_get (kcontext, ccache, &cursor);
+ printiferr (err, "while finishing ticket retrieval");
+ }
+
+ if (proxy_flag) {
+ goto outer_cleanup;
+ }
+ // End of first round read
+
if (!err) {
err = krb5_cc_start_seq_get (kcontext, ccache, &cursor);
}
@@ -388,6 +431,7 @@
printiferr (err, "while finishing ticket retrieval");
}
+outer_cleanup:
if (!err) {
flags = KRB5_TC_OPENCLOSE; /* restore OPENCLOSE mode */
err = krb5_cc_set_flags (kcontext, ccache, flags);
--- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java Wed Oct 16 11:23:46 2019 +0200
@@ -49,4 +49,12 @@
public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) {
t.serverAlias = a;
}
+
+ public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) {
+ return t.proxy;
+ }
+
+ public void kerberosTicketSetProxy(KerberosTicket t, KerberosTicket p) {
+ t.proxy = p;
+ }
}
--- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 16 11:23:46 2019 +0200
@@ -29,11 +29,13 @@
import java.util.Date;
import java.util.Arrays;
import java.net.InetAddress;
+import java.util.Objects;
import javax.crypto.SecretKey;
import javax.security.auth.Refreshable;
import javax.security.auth.Destroyable;
import javax.security.auth.RefreshFailedException;
import javax.security.auth.DestroyFailedException;
+
import sun.security.util.HexDumpEncoder;
/**
@@ -190,8 +192,13 @@
* @serial
*/
+ private InetAddress[] clientAddresses;
- private InetAddress[] clientAddresses;
+ /**
+ * Evidence ticket if proxy_impersonator. This field can be accessed
+ * by KerberosSecrets. It's serialized.
+ */
+ KerberosTicket proxy = null;
private transient boolean destroyed = false;
@@ -711,6 +718,7 @@
"Renew Till = " + String.valueOf(renewTill) + "\n" +
"Client Addresses " +
(clientAddresses == null ? " Null " : caddrString.toString() +
+ (proxy == null ? "" : "\nwith a proxy ticket") +
"\n"));
}
@@ -748,6 +756,10 @@
// clientAddress may be null, the array's hashCode is 0
result = result * 37 + Arrays.hashCode(clientAddresses);
+
+ if (proxy != null) {
+ result = result * 37 + proxy.hashCode();
+ }
return result * 37 + Arrays.hashCode(flags);
}
@@ -820,6 +832,10 @@
}
}
+ if (!Objects.equals(proxy, otherTicket.proxy)) {
+ return false;
+ }
+
return true;
}
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java Wed Oct 16 11:23:46 2019 +0200
@@ -617,6 +617,8 @@
if (myCred == null) {
myCred = Krb5InitCredential.getInstance(caller, myName,
GSSCredential.DEFAULT_LIFETIME);
+ myCred = Krb5ProxyCredential.tryImpersonation(
+ caller, (Krb5InitCredential)myCred);
} else if (!myCred.isInitiatorCredential()) {
throw new GSSException(errorCode, -1,
"No TGT available");
@@ -653,8 +655,8 @@
// highly consider just calling:
// Subject.getSubject
// SubjectComber.find
- // instead of Krb5Util.getTicket
- return Krb5Util.getTicket(
+ // instead of Krb5Util.getServiceTicket
+ return Krb5Util.getServiceTicket(
GSSCaller.CALLER_UNKNOWN,
// since it's useSubjectCredsOnly here,
// don't worry about the null
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java Wed Oct 16 11:23:46 2019 +0200
@@ -57,6 +57,7 @@
private Krb5NameElement name;
@SuppressWarnings("serial") // Not statically typed as Serializable
private Credentials krb5Credentials;
+ public KerberosTicket proxyTicket;
private Krb5InitCredential(Krb5NameElement name,
byte[] asn1Encoding,
@@ -175,7 +176,7 @@
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(tgt);
- return new Krb5InitCredential(name,
+ Krb5InitCredential result = new Krb5InitCredential(name,
tgt.getEncoded(),
tgt.getClient(),
clientAlias,
@@ -189,6 +190,9 @@
tgt.getEndTime(),
tgt.getRenewTill(),
tgt.getClientAddresses());
+ result.proxyTicket = KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
+ kerberosTicketGetProxy(tgt);
+ return result;
}
static Krb5InitCredential getInstance(Krb5NameElement name,
@@ -371,9 +375,9 @@
public KerberosTicket run() throws Exception {
// It's OK to use null as serverPrincipal. TGT is almost
// the first ticket for a principal and we use list.
- return Krb5Util.getTicket(
+ return Krb5Util.getInitialTicket(
realCaller,
- clientPrincipal, null, acc);
+ clientPrincipal, acc);
}});
} catch (PrivilegedActionException e) {
GSSException ge =
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, 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
@@ -124,6 +124,8 @@
usage == GSSCredential.INITIATE_AND_ACCEPT) {
credElement = Krb5InitCredential.getInstance
(caller, (Krb5NameElement) name, initLifetime);
+ credElement = Krb5ProxyCredential.tryImpersonation(
+ caller, (Krb5InitCredential)credElement);
checkInitCredPermission
((Krb5NameElement) credElement.getName());
} else if (usage == GSSCredential.ACCEPT_ONLY) {
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, 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
@@ -144,7 +144,7 @@
return new Krb5NameElement(principalName, gssNameStr, gssNameType);
}
- static Krb5NameElement getInstance(PrincipalName principalName) {
+ public static Krb5NameElement getInstance(PrincipalName principalName) {
return new Krb5NameElement(principalName,
principalName.getName(),
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5ProxyCredential.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5ProxyCredential.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 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
@@ -26,10 +26,17 @@
package sun.security.jgss.krb5;
import org.ietf.jgss.*;
+import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
-import java.util.Date;
+
+import java.io.IOException;
+
+import sun.security.krb5.Credentials;
+import sun.security.krb5.KrbException;
import sun.security.krb5.internal.Ticket;
+import javax.security.auth.kerberos.KerberosTicket;
+
/**
* Implements the krb5 proxy credential element used in constrained
* delegation. It is used in both impersonation (where there is no Kerberos 5
@@ -112,4 +119,24 @@
throw new GSSException(GSSException.FAILURE, -1,
"Only an initiate credentials can impersonate");
}
+
+ // Try to see if a default credential should act as an impersonator.
+ static Krb5CredElement tryImpersonation(GSSCaller caller,
+ Krb5InitCredential initiator) throws GSSException {
+
+ try {
+ KerberosTicket proxy = initiator.proxyTicket;
+ if (proxy != null) {
+ Credentials proxyCreds = Krb5Util.ticketToCreds(proxy);
+ return new Krb5ProxyCredential(initiator,
+ Krb5NameElement.getInstance(proxyCreds.getClient()),
+ proxyCreds.getTicket());
+ } else {
+ return initiator;
+ }
+ } catch (KrbException | IOException e) {
+ throw new GSSException(GSSException.DEFECTIVE_CREDENTIAL, -1,
+ "Cannot create proxy credential");
+ }
+ }
}
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java Wed Oct 16 11:23:46 2019 +0200
@@ -60,11 +60,8 @@
/**
* 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
- * useSubjectCredsOnly is false, then obtain ticket from
- * a LoginContext.
*/
- static KerberosTicket getTicket(GSSCaller caller,
+ static KerberosTicket getServiceTicket(GSSCaller caller,
String clientPrincipal, String serverPrincipal,
AccessControlContext acc) throws LoginException {
@@ -74,11 +71,31 @@
SubjectComber.find(accSubj, serverPrincipal, clientPrincipal,
KerberosTicket.class);
+ return ticket;
+ }
+
+ /**
+ * Retrieves the initial TGT corresponding to the client principal
+ * from the Subject in the specified AccessControlContext.
+ * If the ticket can not be found in the Subject, and if
+ * useSubjectCredsOnly is false, then obtain ticket from
+ * a LoginContext.
+ */
+ static KerberosTicket getInitialTicket(GSSCaller caller,
+ String clientPrincipal,
+ AccessControlContext acc) throws LoginException {
+
+ // Try to get ticket from acc's Subject
+ Subject accSubj = Subject.getSubject(acc);
+ KerberosTicket ticket =
+ SubjectComber.find(accSubj, null, clientPrincipal,
+ KerberosTicket.class);
+
// Try to get ticket from Subject obtained from GSSUtil
if (ticket == null && !GSSUtil.useSubjectCredsOnly(caller)) {
Subject subject = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
ticket = SubjectComber.find(subject,
- serverPrincipal, clientPrincipal, KerberosTicket.class);
+ null, clientPrincipal, KerberosTicket.class);
}
return ticket;
}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java Wed Oct 16 11:23:46 2019 +0200
@@ -59,13 +59,23 @@
KerberosTime endTime;
KerberosTime renewTill;
HostAddresses cAddr;
- EncryptionKey serviceKey;
AuthorizationData authzData;
private static boolean DEBUG = Krb5.DEBUG;
private static CredentialsCache cache;
static boolean alreadyLoaded = false;
private static boolean alreadyTried = false;
+ private Credentials proxy = null;
+
+ public Credentials getProxy() {
+ return proxy;
+ }
+
+ public Credentials setProxy(Credentials proxy) {
+ this.proxy = proxy;
+ return this;
+ }
+
// Read native ticket with session key type in the given list
private static native Credentials acquireDefaultNativeCreds(int[] eTypes);
@@ -361,20 +371,19 @@
return null;
}
- sun.security.krb5.internal.ccache.Credentials tgtCred =
- ccache.getDefaultCreds();
+ Credentials tgtCred = ccache.getInitialCreds();
if (tgtCred == null) {
return null;
}
- if (EType.isSupported(tgtCred.getEType())) {
- return tgtCred.setKrbCreds();
+ if (EType.isSupported(tgtCred.key.getEType())) {
+ return tgtCred;
} else {
if (DEBUG) {
System.out.println(
">>> unsupported key type found the default TGT: " +
- tgtCred.getEType());
+ tgtCred.key.getEType());
}
return null;
}
@@ -409,20 +418,19 @@
cache = CredentialsCache.getInstance();
}
if (cache != null) {
- sun.security.krb5.internal.ccache.Credentials temp =
- cache.getDefaultCreds();
+ Credentials temp = cache.getInitialCreds();
if (temp != null) {
if (DEBUG) {
System.out.println(">>> KrbCreds found the default ticket"
+ " granting ticket in credential cache.");
}
- if (EType.isSupported(temp.getEType())) {
- result = temp.setKrbCreds();
+ if (EType.isSupported(temp.key.getEType())) {
+ result = temp;
} else {
if (DEBUG) {
System.out.println(
">>> unsupported key type found the default TGT: " +
- temp.getEType());
+ temp.key.getEType());
}
}
}
@@ -499,10 +507,6 @@
return cache;
}
- public EncryptionKey getServiceKey() {
- return serviceKey;
- }
-
/*
* Prints out debug info.
*/
--- a/src/java.security.jgss/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java Wed Oct 16 11:23:46 2019 +0200
@@ -28,8 +28,6 @@
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KeyTab;
-import sun.security.krb5.EncryptionKey;
-import sun.security.krb5.PrincipalName;
/**
* An unsafe tunnel to get non-public access to classes in the
@@ -49,4 +47,13 @@
public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t);
public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a);
+ /**
+ * Returns the proxy for a KerberosTicket.
+ */
+ public KerberosTicket kerberosTicketGetProxy(KerberosTicket t);
+
+ /**
+ * Sets the proxy for a KerberosTicket.
+ */
+ public void kerberosTicketSetProxy(KerberosTicket t, KerberosTicket p);
}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -186,7 +186,6 @@
return false;
for (int i = 0; i < name.length(); i++) {
if (name.charAt(i) == '/' ||
- name.charAt(i) == ':' ||
name.charAt(i) == '\0') {
return false;
}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Wed Oct 16 11:23:46 2019 +0200
@@ -325,16 +325,13 @@
}
/**
- * Reads the next cred in stream.
- * @return the next cred, null if ticket or second_ticket unparseable.
+ * Reads the next cred or config entry in stream.
+ * @return the next cred or config entry, null if data unparseable.
*
- * Note: MIT krb5 1.8.1 might generate a config entry with server principal
- * X-CACHECONF:/krb5_ccache_conf_data/fast_avail/krbtgt/REALM@REALM. The
- * entry is used by KDC to inform the client that it support certain
- * features. Its ticket is not a valid krb5 ticket and thus this method
- * returns null.
+ * When data is unparseable, this method makes sure the correct number of
+ * bytes are consumed so it's safe to start reading the next element.
*/
- Credentials readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
+ Object readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
PrincipalName cpname = null;
try {
cpname = readPrincipal(version);
@@ -396,12 +393,23 @@
}
try {
+ if (spname.getRealmString().equals("X-CACHECONF:")) {
+ String[] nameParts = spname.getNameStrings();
+ if (nameParts[0].equals("krb5_ccache_conf_data")) {
+ return new CredentialsCache.ConfigEntry(nameParts[1],
+ nameParts.length > 2 ? new PrincipalName(nameParts[2]) : null,
+ ticketData);
+ }
+ }
return new Credentials(cpname, spname, key, authtime, starttime,
- endtime, renewTill, skey, tFlags,
- addrs, auData,
- ticketData != null ? new Ticket(ticketData) : null,
- ticketData2 != null ? new Ticket(ticketData2) : null);
+ endtime, renewTill, skey, tFlags,
+ addrs, auData,
+ ticketData != null ? new Ticket(ticketData) : null,
+ ticketData2 != null ? new Ticket(ticketData2) : null);
} catch (Exception e) { // If any of new Ticket(*) fails.
+ if (DEBUG) {
+ e.printStackTrace(System.out);
+ }
return null;
}
}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheOutputStream.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheOutputStream.java Wed Oct 16 11:23:46 2019 +0200
@@ -31,7 +31,6 @@
package sun.security.krb5.internal.ccache;
import java.io.IOException;
-import java.io.FileOutputStream;
import java.io.OutputStream;
import sun.security.krb5.internal.util.KrbDataOutputStream;
import sun.security.krb5.*;
@@ -98,6 +97,21 @@
writeTicket(creds.secondTicket);
}
+ public void addConfigEntry(PrincipalName cname, CredentialsCache.ConfigEntry e)
+ throws IOException {
+ cname.writePrincipal(this);
+ e.getSName().writePrincipal(this);
+ write16(0); write16(0); write32(0);
+ write32(0); write32(0); write32(0); write32(0);
+ write8(0);
+ write32(0);
+ write32(0);
+ write32(0);
+ write32(e.getData().length);
+ write(e.getData());
+ write32(0);
+ }
+
void writeTicket(Ticket t) throws IOException, Asn1Exception {
if (t == null) {
write32(0);
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/Credentials.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/Credentials.java Wed Oct 16 11:23:46 2019 +0200
@@ -169,6 +169,18 @@
return sname;
}
+ public Ticket getTicket() throws RealmException {
+ return ticket;
+ }
+
+ public PrincipalName getServicePrincipal2() throws RealmException {
+ return secondTicket == null ? null : secondTicket.sname;
+ }
+
+ public PrincipalName getClientPrincipal() throws RealmException {
+ return cname;
+ }
+
public sun.security.krb5.Credentials setKrbCreds() {
// Note: We will not pass authorizationData to s.s.k.Credentials. The
// field in that class will be passed to Krb5Context as the return
@@ -209,7 +221,15 @@
return key.getEType();
}
+ public EncryptionKey getKey() {
+ return key;
+ }
+
public int getTktEType() {
return ticket.encPart.getEType();
}
+
+ public int getTktEType2() {
+ return (secondTicket == null) ? 0 : secondTicket.encPart.getEType();
+ }
}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CredentialsCache.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CredentialsCache.java Wed Oct 16 11:23:46 2019 +0200
@@ -32,14 +32,9 @@
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
-import java.util.StringTokenizer;
-import java.util.Vector;
+
+import java.util.List;
import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
/**
* CredentialsCache stores credentials(tickets, session keys, etc) in a semi-permanent store
@@ -120,6 +115,62 @@
public abstract void save() throws IOException, KrbException;
public abstract Credentials[] getCredsList();
public abstract Credentials getDefaultCreds();
+ public abstract sun.security.krb5.Credentials getInitialCreds();
public abstract Credentials getCreds(PrincipalName sname);
public abstract Credentials getCreds(LoginOptions options, PrincipalName sname);
+ public abstract void addConfigEntry(ConfigEntry e);
+ public abstract List<ConfigEntry> getConfigEntries();
+
+ public ConfigEntry getConfigEntry(String name) {
+ List<ConfigEntry> entries = getConfigEntries();
+ if (entries != null) {
+ for (ConfigEntry e : entries) {
+ if (e.getName().equals(name)) {
+ return e;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static class ConfigEntry {
+
+ public ConfigEntry(String name, PrincipalName princ, byte[] data) {
+ this.name = name;
+ this.princ = princ;
+ this.data = data;
+ }
+
+ private final String name;
+ private final PrincipalName princ;
+ private final byte[] data; // not worth cloning
+
+ public String getName() {
+ return name;
+ }
+
+ public PrincipalName getPrinc() {
+ return princ;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return name + (princ != null ? ("." + princ) : "")
+ + ": " + new String(data);
+ }
+
+ public PrincipalName getSName() {
+ try {
+ return new PrincipalName("krb5_ccache_conf_data/" + name
+ + (princ != null ? ("/" + princ) : "")
+ + "@X-CACHECONF:");
+ } catch (RealmException e) {
+ throw new AssertionError(e);
+ }
+ }
+ }
}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -36,6 +36,12 @@
import sun.security.action.GetPropertyAction;
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
+import sun.security.util.SecurityProperties;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import java.io.IOException;
@@ -182,9 +188,13 @@
primaryPrincipal = p;
credentialsList = new Vector<Credentials>();
while (cis.available() > 0) {
- Credentials cred = cis.readCred(version);
+ Object cred = cis.readCred(version);
if (cred != null) {
- credentialsList.addElement(cred);
+ if (cred instanceof Credentials) {
+ credentialsList.addElement((Credentials)cred);
+ } else {
+ addConfigEntry((CredentialsCache.ConfigEntry)cred);
+ }
}
}
}
@@ -255,6 +265,9 @@
cos.addCreds(tmp[i]);
}
}
+ for (ConfigEntry e : getConfigEntries()) {
+ cos.addConfigEntry(primaryPrincipal, e);
+ }
}
}
@@ -307,6 +320,17 @@
}
}
+ private List<ConfigEntry> configEntries = new ArrayList<>();
+
+ @Override
+ public void addConfigEntry(ConfigEntry e) {
+ configEntries.add(e);
+ }
+
+ @Override
+ public List<ConfigEntry> getConfigEntries() {
+ return Collections.unmodifiableList(configEntries);
+ }
/**
* Gets a credentials for a specified service.
@@ -326,6 +350,81 @@
return null;
}
+ public sun.security.krb5.Credentials getInitialCreds() {
+
+ Credentials defaultCreds = getDefaultCreds();
+ if (defaultCreds == null) {
+ return null;
+ }
+ sun.security.krb5.Credentials tgt = defaultCreds.setKrbCreds();
+
+ CredentialsCache.ConfigEntry entry = getConfigEntry("proxy_impersonator");
+ if (entry == null) {
+ if (DEBUG) {
+ System.out.println("get normal credential");
+ }
+ return tgt;
+ }
+
+ boolean force;
+ String prop = SecurityProperties.privilegedGetOverridable(
+ "jdk.security.krb5.default.initiate.credential");
+ if (prop == null) {
+ prop = "always-impersonate";
+ }
+ switch (prop) {
+ case "no-impersonate": // never try impersonation
+ if (DEBUG) {
+ System.out.println("get normal credential");
+ }
+ return tgt;
+ case "try-impersonate":
+ force = false;
+ break;
+ case "always-impersonate":
+ force = true;
+ break;
+ default:
+ throw new RuntimeException(
+ "Invalid jdk.security.krb5.default.initiate.credential");
+ }
+
+ try {
+ PrincipalName service = new PrincipalName(
+ new String(entry.getData(), StandardCharsets.UTF_8));
+ if (!tgt.getClient().equals(service)) {
+ if (DEBUG) {
+ System.out.println("proxy_impersonator does not match service name");
+ }
+ return force ? null : tgt;
+ }
+ PrincipalName client = getPrimaryPrincipal();
+ Credentials proxy = null;
+ for (Credentials c : getCredsList()) {
+ if (c.getClientPrincipal().equals(client)
+ && c.getServicePrincipal().equals(service)) {
+ proxy = c;
+ break;
+ }
+ }
+ if (proxy == null) {
+ if (DEBUG) {
+ System.out.println("Cannot find evidence ticket in ccache");
+ }
+ return force ? null : tgt;
+ }
+ if (DEBUG) {
+ System.out.println("Get proxied credential");
+ }
+ return tgt.setProxy(proxy.setKrbCreds());
+ } catch (KrbException e) {
+ if (DEBUG) {
+ System.out.println("Impersonation with ccache failed");
+ }
+ return force ? null : tgt;
+ }
+ }
+
public Credentials getDefaultCreds() {
Credentials[] list = getCredsList();
if (list == null) {
--- a/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,6 +31,8 @@
package sun.security.krb5.internal.tools;
import java.net.InetAddress;
+import java.util.List;
+
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.*;
@@ -249,6 +251,8 @@
String endtime;
String renewTill;
String servicePrincipal;
+ PrincipalName servicePrincipal2;
+ String clientPrincipal;
if (creds[i].getStartTime() != null) {
starttime = format(creds[i].getStartTime());
} else {
@@ -260,6 +264,18 @@
System.out.println("[" + (i + 1) + "] " +
" Service Principal: " +
servicePrincipal);
+ servicePrincipal2 =
+ creds[i].getServicePrincipal2();
+ if (servicePrincipal2 != null) {
+ System.out.println(" Second Service: "
+ + servicePrincipal2);
+ }
+ clientPrincipal =
+ creds[i].getClientPrincipal().toString();
+ if (!clientPrincipal.equals(defaultPrincipal)) {
+ System.out.println(" Client Principal: " +
+ clientPrincipal);
+ }
System.out.println(" Valid starting: " + starttime);
System.out.println(" Expires: " + endtime);
if (creds[i].getRenewTill() != null) {
@@ -270,8 +286,15 @@
if (options[0] == 'e') {
String eskey = EType.toString(creds[i].getEType());
String etkt = EType.toString(creds[i].getTktEType());
- System.out.println(" EType (skey, tkt): "
- + eskey + ", " + etkt);
+ if (creds[i].getTktEType2() == 0) {
+ System.out.println(" EType (skey, tkt): "
+ + eskey + ", " + etkt);
+ } else {
+ String etkt2 = EType.toString(creds[i].getTktEType2());
+ System.out.println(" EType (skey, tkts): "
+ + eskey + ", " + etkt
+ + ", " + etkt2);
+ }
}
if (options[1] == 'f') {
System.out.println(" Flags: " +
@@ -310,6 +333,15 @@
} else {
System.out.println("\nNo entries found.");
}
+
+ List<CredentialsCache.ConfigEntry> configEntries
+ = cache.getConfigEntries();
+ if (configEntries != null && !configEntries.isEmpty()) {
+ System.out.println("\nConfig entries:");
+ for (CredentialsCache.ConfigEntry e : configEntries) {
+ System.out.println(" " + e);
+ }
+ }
}
void displayMessage(String target) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -40,7 +40,7 @@
* The XPath class wraps an expression object and provides general services
* for execution of that expression.
* @xsl.usage advanced
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
*/
public class XPath implements Serializable, ExpressionOwner
{
@@ -179,10 +179,12 @@
else if (MATCH == type)
parser.initMatchPattern(compiler, exprString, prefixResolver);
else
- throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, new Object[]{Integer.toString(type)})); //"Can not deal with XPath type: " + type);
+ throw new RuntimeException(XSLMessages.createXPATHMessage(
+ XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE,
+ new Object[]{Integer.toString(type)}));
// System.out.println("----------------");
- Expression expr = compiler.compile(0);
+ Expression expr = compiler.compileExpression(0);
// System.out.println("expr: "+expr);
this.setExpression(expr);
@@ -234,7 +236,7 @@
//"Can not deal with XPath type: " + type);
// System.out.println("----------------");
- Expression expr = compiler.compile(0);
+ Expression expr = compiler.compileExpression(0);
// System.out.println("expr: "+expr);
this.setExpression(expr);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java Wed Oct 16 11:23:46 2019 +0200
@@ -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,7 +37,7 @@
* Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP,
* op codes.
* @see <a href="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a>
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
*/
public class FilterExprWalker extends AxesWalker
{
@@ -77,7 +77,7 @@
m_mustHardReset = true;
case OpCodes.OP_GROUP :
case OpCodes.OP_VARIABLE :
- m_expr = compiler.compile(opPos);
+ m_expr = compiler.compileExpression(opPos);
m_expr.exprSetParent(this);
//if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof com.sun.org.apache.xalan.internal.templates.FuncKey))
if(m_expr instanceof com.sun.org.apache.xpath.internal.operations.Variable)
@@ -87,7 +87,7 @@
}
break;
default :
- m_expr = compiler.compile(opPos + 2);
+ m_expr = compiler.compileExpression(opPos + 2);
m_expr.exprSetParent(this);
}
// if(m_expr instanceof WalkingIterator)
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -41,7 +41,7 @@
* which are built from the opcode map output, and an analysis engine
* for the location path expressions in order to provide optimization hints.
*
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
*/
public class WalkerFactory
{
@@ -1008,10 +1008,10 @@
case OpCodes.OP_EXTFUNCTION :
case OpCodes.OP_FUNCTION :
case OpCodes.OP_GROUP :
- expr = compiler.compile(opPos);
+ expr = compiler.compileExpression(opPos);
break;
default :
- expr = compiler.compile(opPos + 2);
+ expr = compiler.compileExpression(opPos + 2);
}
axis = Axis.FILTEREDLIST;
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,6 +1,5 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -70,9 +69,12 @@
* of operation codes (op map) and then builds from that into an Expression
* tree.
* @xsl.usage advanced
+ * @LastModified: May 2019
*/
public class Compiler extends OpMap
{
+ // count the number of operations or calls to compileOperation
+ int countOp;
/**
* Construct a Compiler object with a specific ErrorListener and
@@ -106,15 +108,40 @@
/**
* Execute the XPath object from a given opcode position.
+ *
+ * Note that this method is added so that when StackOverflowError is caught
+ * the address space can be freed to this point allowing further activities
+ * such as reporting the error.
+ *
* @param opPos The current position in the xpath.m_opMap array.
* @return The result of the XPath.
*
* @throws TransformerException if there is a syntax or other error.
* @xsl.usage advanced
*/
- public Expression compile(int opPos) throws TransformerException
+ public Expression compileExpression(int opPos) throws TransformerException
+ {
+ try {
+ countOp = 0;
+ return compile(opPos);
+ } catch (StackOverflowError sof) {
+ error(XPATHErrorResources.ER_COMPILATION_TOO_MANY_OPERATION, new Object[]{countOp});
+ }
+ return null;
+ }
+
+ /**
+ * This method handles the actual compilation process. It is called from the
+ * compileExpression method as well as the subsequent processes. See the note
+ * for compileExpression.
+ *
+ * @param opPos The current position in the xpath.m_opMap array.
+ * @return The result of the XPath.
+ *
+ * @throws TransformerException if there is a syntax or other error.
+ */
+ private Expression compile(int opPos) throws TransformerException
{
-
int op = getOp(opPos);
Expression expr = null;
@@ -210,6 +237,7 @@
private Expression compileOperation(Operation operation, int opPos)
throws TransformerException
{
+ ++countOp;
int leftPos = getFirstChildPos(opPos);
int rightPos = getNextOpPos(leftPos);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -34,6 +34,7 @@
* Tokenizes and parses XPath expressions. This should really be named
* XPathParserImpl, and may be renamed in the future.
* @xsl.usage general
+ * @LastModified: May 2019
*/
public class XPathParser
{
@@ -71,6 +72,9 @@
protected final static int FILTER_MATCH_PRIMARY = 1;
protected final static int FILTER_MATCH_PREDICATES = 2;
+ // counts open predicates
+ private int countPredicate;
+
/**
* The parser constructor.
*/
@@ -157,6 +161,9 @@
}
else
throw e;
+ } catch (StackOverflowError sof) {
+ error(XPATHErrorResources.ER_PREDICATE_TOO_MANY_OPEN,
+ new Object[]{m_token, m_queueMark, countPredicate});
}
compiler.shrink();
@@ -190,7 +197,12 @@
m_ops.setOp(OpMap.MAPINDEX_LENGTH, 2);
nextToken();
- Pattern();
+ try {
+ Pattern();
+ } catch (StackOverflowError sof) {
+ error(XPATHErrorResources.ER_PREDICATE_TOO_MANY_OPEN,
+ new Object[]{m_token, m_queueMark, countPredicate});
+ }
if (null != m_token)
{
@@ -741,7 +753,7 @@
*/
protected void Expr() throws javax.xml.transform.TransformerException
{
- OrExpr();
+ OrExpr();
}
/**
@@ -1883,11 +1895,12 @@
*/
protected void Predicate() throws javax.xml.transform.TransformerException
{
-
if (tokenIs('['))
{
+ countPredicate++;
nextToken();
PredicateExpr();
+ countPredicate--;
consumeExpected(']');
}
}
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,6 +1,5 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -32,6 +31,7 @@
* Also you need to update the count of messages(MAX_CODE)or
* the count of warnings(MAX_WARNING) [ Information purpose only]
* @xsl.usage advanced
+ * @LastModified: May 2019
*/
public class XPATHErrorResources extends ListResourceBundle
{
@@ -150,6 +150,10 @@
"ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG";
public static final String ER_PREDICATE_ILLEGAL_SYNTAX =
"ER_PREDICATE_ILLEGAL_SYNTAX";
+ public static final String ER_PREDICATE_TOO_MANY_OPEN =
+ "ER_PREDICATE_TOO_MANY_OPEN";
+ public static final String ER_COMPILATION_TOO_MANY_OPERATION =
+ "ER_COMPILATION_TOO_MANY_OPERATION";
public static final String ER_ILLEGAL_AXIS_NAME = "ER_ILLEGAL_AXIS_NAME";
public static final String ER_UNKNOWN_NODETYPE = "ER_UNKNOWN_NODETYPE";
public static final String ER_PATTERN_LITERAL_NEEDS_BE_QUOTED =
@@ -464,6 +468,12 @@
{ ER_PREDICATE_ILLEGAL_SYNTAX,
"'..[predicate]' or '.[predicate]' is illegal syntax. Use 'self::node()[predicate]' instead."},
+ { ER_PREDICATE_TOO_MANY_OPEN,
+ "Stack overflow while parsing {0} at {1}. Too many open predicates({2})."},
+
+ { ER_COMPILATION_TOO_MANY_OPERATION,
+ "Stack overflow while compiling the expression. Too many operations({0})."},
+
{ ER_ILLEGAL_AXIS_NAME,
"illegal axis name: {0}"},
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
--- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c Wed Oct 16 11:23:46 2019 +0200
@@ -31,336 +31,14 @@
#include <elf.h>
#include <link.h>
#include "libproc_impl.h"
+#include "ps_core_common.h"
#include "proc_service.h"
#include "salibelf.h"
-#include "cds.h"
// This file has the libproc implementation to read core files.
// For live processes, refer to ps_proc.c. Portions of this is adapted
// /modelled after Solaris libproc.so (in particular Pcore.c)
-//----------------------------------------------------------------------
-// ps_prochandle cleanup helper functions
-
-// close all file descriptors
-static void close_files(struct ps_prochandle* ph) {
- lib_info* lib = NULL;
-
- // close core file descriptor
- if (ph->core->core_fd >= 0)
- close(ph->core->core_fd);
-
- // close exec file descriptor
- if (ph->core->exec_fd >= 0)
- close(ph->core->exec_fd);
-
- // close interp file descriptor
- if (ph->core->interp_fd >= 0)
- close(ph->core->interp_fd);
-
- // close class share archive file
- if (ph->core->classes_jsa_fd >= 0)
- close(ph->core->classes_jsa_fd);
-
- // close all library file descriptors
- lib = ph->libs;
- while (lib) {
- int fd = lib->fd;
- if (fd >= 0 && fd != ph->core->exec_fd) {
- close(fd);
- }
- lib = lib->next;
- }
-}
-
-// clean all map_info stuff
-static void destroy_map_info(struct ps_prochandle* ph) {
- map_info* map = ph->core->maps;
- while (map) {
- map_info* next = map->next;
- free(map);
- map = next;
- }
-
- if (ph->core->map_array) {
- free(ph->core->map_array);
- }
-
- // Part of the class sharing workaround
- map = ph->core->class_share_maps;
- while (map) {
- map_info* next = map->next;
- free(map);
- map = next;
- }
-}
-
-// ps_prochandle operations
-static void core_release(struct ps_prochandle* ph) {
- if (ph->core) {
- close_files(ph);
- destroy_map_info(ph);
- free(ph->core);
- }
-}
-
-static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
- map_info* map;
- if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
- print_debug("can't allocate memory for map_info\n");
- return NULL;
- }
-
- // initialize map
- map->fd = fd;
- map->offset = offset;
- map->vaddr = vaddr;
- map->memsz = memsz;
- return map;
-}
-
-// add map info with given fd, offset, vaddr and memsz
-static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
- uintptr_t vaddr, size_t memsz) {
- map_info* map;
- if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
- return NULL;
- }
-
- // add this to map list
- map->next = ph->core->maps;
- ph->core->maps = map;
- ph->core->num_maps++;
-
- return map;
-}
-
-// Part of the class sharing workaround
-static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
- uintptr_t vaddr, size_t memsz) {
- map_info* map;
- if ((map = allocate_init_map(ph->core->classes_jsa_fd,
- offset, vaddr, memsz)) == NULL) {
- return NULL;
- }
-
- map->next = ph->core->class_share_maps;
- ph->core->class_share_maps = map;
- return map;
-}
-
-// Return the map_info for the given virtual address. We keep a sorted
-// array of pointers in ph->map_array, so we can binary search.
-static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
- int mid, lo = 0, hi = ph->core->num_maps - 1;
- map_info *mp;
-
- while (hi - lo > 1) {
- mid = (lo + hi) / 2;
- if (addr >= ph->core->map_array[mid]->vaddr) {
- lo = mid;
- } else {
- hi = mid;
- }
- }
-
- if (addr < ph->core->map_array[hi]->vaddr) {
- mp = ph->core->map_array[lo];
- } else {
- mp = ph->core->map_array[hi];
- }
-
- if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
- return (mp);
- }
-
-
- // Part of the class sharing workaround
- // Unfortunately, we have no way of detecting -Xshare state.
- // Check out the share maps atlast, if we don't find anywhere.
- // This is done this way so to avoid reading share pages
- // ahead of other normal maps. For eg. with -Xshare:off we don't
- // want to prefer class sharing data to data from core.
- mp = ph->core->class_share_maps;
- if (mp) {
- print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
- }
- while (mp) {
- if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
- print_debug("located map_info at 0x%lx from class share maps\n", addr);
- return (mp);
- }
- mp = mp->next;
- }
-
- print_debug("can't locate map_info at 0x%lx\n", addr);
- return (NULL);
-}
-
-//---------------------------------------------------------------
-// Part of the class sharing workaround:
-//
-// With class sharing, pages are mapped from classes.jsa file.
-// The read-only class sharing pages are mapped as MAP_SHARED,
-// PROT_READ pages. These pages are not dumped into core dump.
-// With this workaround, these pages are read from classes.jsa.
-
-static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
- jboolean i;
- if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
- *pvalue = i;
- return true;
- } else {
- return false;
- }
-}
-
-static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
- uintptr_t uip;
- if (ps_pdread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
- *pvalue = uip;
- return true;
- } else {
- return false;
- }
-}
-
-// used to read strings from debuggee
-static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
- size_t i = 0;
- char c = ' ';
-
- while (c != '\0') {
- if (ps_pdread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
- return false;
- }
- if (i < size - 1) {
- buf[i] = c;
- } else {
- // smaller buffer
- return false;
- }
- i++; addr++;
- }
-
- buf[i] = '\0';
- return true;
-}
-
-#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
-// mangled name of Arguments::SharedArchivePath
-#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
-#define LIBJVM_NAME "/libjvm.so"
-
-static bool init_classsharing_workaround(struct ps_prochandle* ph) {
- lib_info* lib = ph->libs;
- while (lib != NULL) {
- // we are iterating over shared objects from the core dump. look for
- // libjvm.so.
- const char *jvm_name = 0;
- if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
- char classes_jsa[PATH_MAX];
- CDSFileMapHeaderBase header;
- int fd = -1;
- int m = 0;
- size_t n = 0;
- uintptr_t base = 0, useSharedSpacesAddr = 0;
- uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
- jboolean useSharedSpaces = 0;
- map_info* mi = 0;
-
- memset(classes_jsa, 0, sizeof(classes_jsa));
- jvm_name = lib->name;
- useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
- if (useSharedSpacesAddr == 0) {
- print_debug("can't lookup 'UseSharedSpaces' flag\n");
- return false;
- }
-
- // Hotspot vm types are not exported to build this library. So
- // using equivalent type jboolean to read the value of
- // UseSharedSpaces which is same as hotspot type "bool".
- if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
- print_debug("can't read the value of 'UseSharedSpaces' flag\n");
- return false;
- }
-
- if ((int)useSharedSpaces == 0) {
- print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
- return true;
- }
-
- sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
- if (sharedArchivePathAddrAddr == 0) {
- print_debug("can't lookup shared archive path symbol\n");
- return false;
- }
-
- if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
- print_debug("can't read shared archive path pointer\n");
- return false;
- }
-
- if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
- print_debug("can't read shared archive path value\n");
- return false;
- }
-
- print_debug("looking for %s\n", classes_jsa);
- // open the class sharing archive file
- fd = pathmap_open(classes_jsa);
- if (fd < 0) {
- print_debug("can't open %s!\n", classes_jsa);
- ph->core->classes_jsa_fd = -1;
- return false;
- } else {
- print_debug("opened %s\n", classes_jsa);
- }
-
- // read CDSFileMapHeaderBase from the file
- memset(&header, 0, sizeof(CDSFileMapHeaderBase));
- if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
- != sizeof(CDSFileMapHeaderBase)) {
- print_debug("can't read shared archive file map header from %s\n", classes_jsa);
- close(fd);
- return false;
- }
-
- // check file magic
- if (header._magic != CDS_ARCHIVE_MAGIC) {
- print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
- classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
- close(fd);
- return false;
- }
-
- // check version
- if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
- print_debug("%s has wrong shared archive file version %d, expecting %d\n",
- classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
- close(fd);
- return false;
- }
-
- ph->core->classes_jsa_fd = fd;
- // add read-only maps from classes.jsa to the list of maps
- for (m = 0; m < NUM_CDS_REGIONS; m++) {
- if (header._space[m]._read_only) {
- base = (uintptr_t) header._space[m]._addr._base;
- // no need to worry about the fractional pages at-the-end.
- // possible fractional pages are handled by core_read_data.
- add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
- base, (size_t) header._space[m]._used);
- print_debug("added a share archive map at 0x%lx\n", base);
- }
- }
- return true;
- }
- lib = lib->next;
- }
- return true;
-}
-
//---------------------------------------------------------------------------
// functions to handle map_info
--- a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <stddef.h>
#include "libproc_impl.h"
-#include "cds.h"
+#include "ps_core_common.h"
#ifdef __APPLE__
#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
@@ -39,332 +39,6 @@
// For live processes, refer to ps_proc.c. Portions of this is adapted
// /modelled after Solaris libproc.so (in particular Pcore.c)
-//----------------------------------------------------------------------
-// ps_prochandle cleanup helper functions
-
-// close all file descriptors
-static void close_files(struct ps_prochandle* ph) {
- lib_info* lib = NULL;
-
- // close core file descriptor
- if (ph->core->core_fd >= 0)
- close(ph->core->core_fd);
-
- // close exec file descriptor
- if (ph->core->exec_fd >= 0)
- close(ph->core->exec_fd);
-
- // close interp file descriptor
- if (ph->core->interp_fd >= 0)
- close(ph->core->interp_fd);
-
- // close class share archive file
- if (ph->core->classes_jsa_fd >= 0)
- close(ph->core->classes_jsa_fd);
-
- // close all library file descriptors
- lib = ph->libs;
- while (lib) {
- int fd = lib->fd;
- if (fd >= 0 && fd != ph->core->exec_fd) {
- close(fd);
- }
- lib = lib->next;
- }
-}
-
-// clean all map_info stuff
-static void destroy_map_info(struct ps_prochandle* ph) {
- map_info* map = ph->core->maps;
- while (map) {
- map_info* next = map->next;
- free(map);
- map = next;
- }
-
- if (ph->core->map_array) {
- free(ph->core->map_array);
- }
-
- // Part of the class sharing workaround
- map = ph->core->class_share_maps;
- while (map) {
- map_info* next = map->next;
- free(map);
- map = next;
- }
-}
-
-// ps_prochandle operations
-static void core_release(struct ps_prochandle* ph) {
- if (ph->core) {
- close_files(ph);
- destroy_map_info(ph);
- free(ph->core);
- }
-}
-
-static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
- map_info* map;
- if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
- print_debug("can't allocate memory for map_info\n");
- return NULL;
- }
-
- // initialize map
- map->fd = fd;
- map->offset = offset;
- map->vaddr = vaddr;
- map->memsz = memsz;
- return map;
-}
-
-// add map info with given fd, offset, vaddr and memsz
-static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
- uintptr_t vaddr, size_t memsz) {
- map_info* map;
- if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
- return NULL;
- }
-
- // add this to map list
- map->next = ph->core->maps;
- ph->core->maps = map;
- ph->core->num_maps++;
-
- return map;
-}
-
-// Part of the class sharing workaround
-static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
- uintptr_t vaddr, size_t memsz) {
- map_info* map;
- if ((map = allocate_init_map(ph->core->classes_jsa_fd,
- offset, vaddr, memsz)) == NULL) {
- return NULL;
- }
-
- map->next = ph->core->class_share_maps;
- ph->core->class_share_maps = map;
- return map;
-}
-
-// Return the map_info for the given virtual address. We keep a sorted
-// array of pointers in ph->map_array, so we can binary search.
-static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
- int mid, lo = 0, hi = ph->core->num_maps - 1;
- map_info *mp;
-
- while (hi - lo > 1) {
- mid = (lo + hi) / 2;
- if (addr >= ph->core->map_array[mid]->vaddr) {
- lo = mid;
- } else {
- hi = mid;
- }
- }
-
- if (addr < ph->core->map_array[hi]->vaddr) {
- mp = ph->core->map_array[lo];
- } else {
- mp = ph->core->map_array[hi];
- }
-
- if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
- return (mp);
- }
-
-
- // Part of the class sharing workaround
- // Unfortunately, we have no way of detecting -Xshare state.
- // Check out the share maps atlast, if we don't find anywhere.
- // This is done this way so to avoid reading share pages
- // ahead of other normal maps. For eg. with -Xshare:off we don't
- // want to prefer class sharing data to data from core.
- mp = ph->core->class_share_maps;
- if (mp) {
- print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
- }
- while (mp) {
- if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
- print_debug("located map_info at 0x%lx from class share maps\n", addr);
- return (mp);
- }
- mp = mp->next;
- }
-
- print_debug("can't locate map_info at 0x%lx\n", addr);
- return (NULL);
-}
-
-//---------------------------------------------------------------
-// Part of the class sharing workaround:
-//
-// With class sharing, pages are mapped from classes.jsa file.
-// The read-only class sharing pages are mapped as MAP_SHARED,
-// PROT_READ pages. These pages are not dumped into core dump.
-// With this workaround, these pages are read from classes.jsa.
-
-static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
- jboolean i;
- if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
- *pvalue = i;
- return true;
- } else {
- return false;
- }
-}
-
-static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
- uintptr_t uip;
- if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
- *pvalue = uip;
- return true;
- } else {
- return false;
- }
-}
-
-// used to read strings from debuggee
-static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
- size_t i = 0;
- char c = ' ';
-
- while (c != '\0') {
- if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
- return false;
- }
- if (i < size - 1) {
- buf[i] = c;
- } else {
- // smaller buffer
- return false;
- }
- i++; addr++;
- }
- buf[i] = '\0';
- return true;
-}
-
-// mangled name of Arguments::SharedArchivePath
-#define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
-
-#ifdef __APPLE__
-#define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
-#define LIBJVM_NAME "/libjvm.dylib"
-#else
-#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
-#define LIBJVM_NAME "/libjvm.so"
-#endif // __APPLE_
-
-static bool init_classsharing_workaround(struct ps_prochandle* ph) {
- int m;
- size_t n;
- lib_info* lib = ph->libs;
- while (lib != NULL) {
- // we are iterating over shared objects from the core dump. look for
- // libjvm.so.
- const char *jvm_name = 0;
- if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
- char classes_jsa[PATH_MAX];
- CDSFileMapHeaderBase header;
- int fd = -1;
- uintptr_t base = 0, useSharedSpacesAddr = 0;
- uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
- jboolean useSharedSpaces = 0;
-
- memset(classes_jsa, 0, sizeof(classes_jsa));
- jvm_name = lib->name;
- useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
- if (useSharedSpacesAddr == 0) {
- print_debug("can't lookup 'UseSharedSpaces' flag\n");
- return false;
- }
-
- // Hotspot vm types are not exported to build this library. So
- // using equivalent type jboolean to read the value of
- // UseSharedSpaces which is same as hotspot type "bool".
- if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
- print_debug("can't read the value of 'UseSharedSpaces' flag\n");
- return false;
- }
-
- if ((int)useSharedSpaces == 0) {
- print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
- return true;
- }
-
- sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
- if (sharedArchivePathAddrAddr == 0) {
- print_debug("can't lookup shared archive path symbol\n");
- return false;
- }
-
- if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
- print_debug("can't read shared archive path pointer\n");
- return false;
- }
-
- if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
- print_debug("can't read shared archive path value\n");
- return false;
- }
-
- print_debug("looking for %s\n", classes_jsa);
- // open the class sharing archive file
- fd = pathmap_open(classes_jsa);
- if (fd < 0) {
- print_debug("can't open %s!\n", classes_jsa);
- ph->core->classes_jsa_fd = -1;
- return false;
- } else {
- print_debug("opened %s\n", classes_jsa);
- }
-
- // read CDSFileMapHeaderBase from the file
- memset(&header, 0, sizeof(CDSFileMapHeaderBase));
- if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
- != sizeof(CDSFileMapHeaderBase)) {
- print_debug("can't read shared archive file map header from %s\n", classes_jsa);
- close(fd);
- return false;
- }
-
- // check file magic
- if (header._magic != CDS_ARCHIVE_MAGIC) {
- print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
- classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
- close(fd);
- return false;
- }
-
- // check version
- if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
- print_debug("%s has wrong shared archive file version %d, expecting %d\n",
- classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
- close(fd);
- return false;
- }
-
- ph->core->classes_jsa_fd = fd;
- // add read-only maps from classes.jsa to the list of maps
- for (m = 0; m < NUM_CDS_REGIONS; m++) {
- if (header._space[m]._read_only) {
- base = (uintptr_t) header._space[m]._addr._base;
- // no need to worry about the fractional pages at-the-end.
- // possible fractional pages are handled by core_read_data.
- add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
- base, (size_t) header._space[m]._used);
- print_debug("added a share archive map at 0x%lx\n", base);
- }
- }
- return true;
- }
- lib = lib->next;
- }
- return true;
-}
-
//---------------------------------------------------------------------------
// functions to handle map_info
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java Wed Oct 16 11:23:46 2019 +0200
@@ -306,12 +306,17 @@
/** This is only for use by the debugging system, and is only
intended for use in the topmost frame, where we are not
guaranteed to be at a PC for which we have a PCDesc. It finds
- the PCDesc with realPC closest to the current PC. */
+ the PCDesc with realPC closest to the current PC that has
+ a valid scope decode offset. */
public PCDesc getPCDescNearDbg(Address pc) {
PCDesc bestGuessPCDesc = null;
long bestDistance = 0;
for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) {
PCDesc pcDesc = new PCDesc(p);
+ if (pcDesc.getScopeDecodeOffset() == DebugInformationRecorder.SERIALIZED_NULL) {
+ // We've observed a serialized null decode offset. Ignore this PcDesc.
+ continue;
+ }
// In case pc is null
long distance = -pcDesc.getRealPC(this).minus(pc);
if ((bestGuessPCDesc == null) ||
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java Wed Oct 16 11:23:46 2019 +0200
@@ -47,7 +47,6 @@
static int REGISTER_MASK_IN_PLACE;
// Types of OopValues
- static int UNUSED_VALUE;
static int OOP_VALUE;
static int NARROWOOP_VALUE;
static int CALLEE_SAVED_VALUE;
@@ -70,7 +69,6 @@
TYPE_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::type_mask_in_place").intValue();
REGISTER_MASK = db.lookupIntConstant("OopMapValue::register_mask").intValue();
REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue();
- UNUSED_VALUE = db.lookupIntConstant("OopMapValue::unused_value").intValue();
OOP_VALUE = db.lookupIntConstant("OopMapValue::oop_value").intValue();
NARROWOOP_VALUE = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue();
CALLEE_SAVED_VALUE = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
@@ -78,7 +76,6 @@
}
public static abstract class OopTypes {
- public static final OopTypes UNUSED_VALUE = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE; }};
public static final OopTypes OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE; }};
public static final OopTypes NARROWOOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE; }};
public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
@@ -111,8 +108,7 @@
public OopTypes getType() {
int which = (getValue() & TYPE_MASK_IN_PLACE);
- if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
- else if (which == OOP_VALUE) return OopTypes.OOP_VALUE;
+ if (which == OOP_VALUE) return OopTypes.OOP_VALUE;
else if (which == NARROWOOP_VALUE) return OopTypes.NARROWOOP_VALUE;
else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
else if (which == DERIVED_OOP_VALUE) return OopTypes.DERIVED_OOP_VALUE;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,385 @@
+/*
+ * 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> // just include something, or else solaris compiler will complain that this file is empty
+
+#if defined(LINUX) || defined(__APPLE__)
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef LINUX
+#include <elf.h>
+#include <link.h>
+#include "proc_service.h"
+#include "salibelf.h"
+#endif
+#include "libproc_impl.h"
+#include "cds.h"
+
+#ifdef __APPLE__
+#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
+#endif
+
+#ifdef LINUX
+// I have no idea why this function is called ps_pread() on macos but ps_pdread on linux.
+#define ps_pread ps_pdread
+#endif
+
+// Common code shared between linux/native/libsaproc/ps_core.c and macosx/native/libsaproc/ps_core.c
+
+//----------------------------------------------------------------------
+// ps_prochandle cleanup helper functions
+
+// close all file descriptors
+static void close_files(struct ps_prochandle* ph) {
+ lib_info* lib = NULL;
+
+ // close core file descriptor
+ if (ph->core->core_fd >= 0)
+ close(ph->core->core_fd);
+
+ // close exec file descriptor
+ if (ph->core->exec_fd >= 0)
+ close(ph->core->exec_fd);
+
+ // close interp file descriptor
+ if (ph->core->interp_fd >= 0)
+ close(ph->core->interp_fd);
+
+ // close class share archive file
+ if (ph->core->classes_jsa_fd >= 0)
+ close(ph->core->classes_jsa_fd);
+
+ // close all library file descriptors
+ lib = ph->libs;
+ while (lib) {
+ int fd = lib->fd;
+ if (fd >= 0 && fd != ph->core->exec_fd) {
+ close(fd);
+ }
+ lib = lib->next;
+ }
+}
+
+// clean all map_info stuff
+static void destroy_map_info(struct ps_prochandle* ph) {
+ map_info* map = ph->core->maps;
+ while (map) {
+ map_info* next = map->next;
+ free(map);
+ map = next;
+ }
+
+ if (ph->core->map_array) {
+ free(ph->core->map_array);
+ }
+
+ // Part of the class sharing workaround
+ map = ph->core->class_share_maps;
+ while (map) {
+ map_info* next = map->next;
+ free(map);
+ map = next;
+ }
+}
+
+// ps_prochandle operations
+void core_release(struct ps_prochandle* ph) {
+ if (ph->core) {
+ close_files(ph);
+ destroy_map_info(ph);
+ free(ph->core);
+ }
+}
+
+static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
+ map_info* map;
+ if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
+ print_debug("can't allocate memory for map_info\n");
+ return NULL;
+ }
+
+ // initialize map
+ map->fd = fd;
+ map->offset = offset;
+ map->vaddr = vaddr;
+ map->memsz = memsz;
+ return map;
+}
+
+// add map info with given fd, offset, vaddr and memsz
+map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
+ uintptr_t vaddr, size_t memsz) {
+ map_info* map;
+ if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
+ return NULL;
+ }
+
+ // add this to map list
+ map->next = ph->core->maps;
+ ph->core->maps = map;
+ ph->core->num_maps++;
+
+ return map;
+}
+
+// Part of the class sharing workaround
+static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
+ uintptr_t vaddr, size_t memsz) {
+ map_info* map;
+ if ((map = allocate_init_map(ph->core->classes_jsa_fd,
+ offset, vaddr, memsz)) == NULL) {
+ return NULL;
+ }
+
+ map->next = ph->core->class_share_maps;
+ ph->core->class_share_maps = map;
+ return map;
+}
+
+// Return the map_info for the given virtual address. We keep a sorted
+// array of pointers in ph->map_array, so we can binary search.
+map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
+ int mid, lo = 0, hi = ph->core->num_maps - 1;
+ map_info *mp;
+
+ while (hi - lo > 1) {
+ mid = (lo + hi) / 2;
+ if (addr >= ph->core->map_array[mid]->vaddr) {
+ lo = mid;
+ } else {
+ hi = mid;
+ }
+ }
+
+ if (addr < ph->core->map_array[hi]->vaddr) {
+ mp = ph->core->map_array[lo];
+ } else {
+ mp = ph->core->map_array[hi];
+ }
+
+ if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
+ return (mp);
+ }
+
+
+ // Part of the class sharing workaround
+ // Unfortunately, we have no way of detecting -Xshare state.
+ // Check out the share maps atlast, if we don't find anywhere.
+ // This is done this way so to avoid reading share pages
+ // ahead of other normal maps. For eg. with -Xshare:off we don't
+ // want to prefer class sharing data to data from core.
+ mp = ph->core->class_share_maps;
+ if (mp) {
+ print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
+ }
+ while (mp) {
+ if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
+ print_debug("located map_info at 0x%lx from class share maps\n", addr);
+ return (mp);
+ }
+ mp = mp->next;
+ }
+
+ print_debug("can't locate map_info at 0x%lx\n", addr);
+ return (NULL);
+}
+
+//---------------------------------------------------------------
+// Part of the class sharing workaround:
+//
+// With class sharing, pages are mapped from classes.jsa file.
+// The read-only class sharing pages are mapped as MAP_SHARED,
+// PROT_READ pages. These pages are not dumped into core dump.
+// With this workaround, these pages are read from classes.jsa.
+
+static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
+ jboolean i;
+ if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
+ *pvalue = i;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
+ uintptr_t uip;
+ if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
+ *pvalue = uip;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// used to read strings from debuggee
+bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
+ size_t i = 0;
+ char c = ' ';
+
+ while (c != '\0') {
+ if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
+ return false;
+ }
+ if (i < size - 1) {
+ buf[i] = c;
+ } else {
+ // smaller buffer
+ return false;
+ }
+ i++; addr++;
+ }
+ buf[i] = '\0';
+ return true;
+}
+
+#ifdef LINUX
+// mangled name of Arguments::SharedArchivePath
+#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
+#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
+#define LIBJVM_NAME "/libjvm.so"
+#endif
+
+#ifdef __APPLE__
+// mangled name of Arguments::SharedArchivePath
+#define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
+#define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
+#define LIBJVM_NAME "/libjvm.dylib"
+#endif
+
+bool init_classsharing_workaround(struct ps_prochandle* ph) {
+ lib_info* lib = ph->libs;
+ while (lib != NULL) {
+ // we are iterating over shared objects from the core dump. look for
+ // libjvm.so.
+ const char *jvm_name = 0;
+ if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
+ char classes_jsa[PATH_MAX];
+ CDSFileMapHeaderBase header;
+ int fd = -1;
+ uintptr_t base = 0, useSharedSpacesAddr = 0;
+ uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
+ jboolean useSharedSpaces = 0;
+ int m;
+ size_t n;
+
+ memset(classes_jsa, 0, sizeof(classes_jsa));
+ jvm_name = lib->name;
+ useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
+ if (useSharedSpacesAddr == 0) {
+ print_debug("can't lookup 'UseSharedSpaces' flag\n");
+ return false;
+ }
+
+ // Hotspot vm types are not exported to build this library. So
+ // using equivalent type jboolean to read the value of
+ // UseSharedSpaces which is same as hotspot type "bool".
+ if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
+ print_debug("can't read the value of 'UseSharedSpaces' flag\n");
+ return false;
+ }
+
+ if ((int)useSharedSpaces == 0) {
+ print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
+ return true;
+ }
+
+ sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
+ if (sharedArchivePathAddrAddr == 0) {
+ print_debug("can't lookup shared archive path symbol\n");
+ return false;
+ }
+
+ if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
+ print_debug("can't read shared archive path pointer\n");
+ return false;
+ }
+
+ if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
+ print_debug("can't read shared archive path value\n");
+ return false;
+ }
+
+ print_debug("looking for %s\n", classes_jsa);
+ // open the class sharing archive file
+ fd = pathmap_open(classes_jsa);
+ if (fd < 0) {
+ print_debug("can't open %s!\n", classes_jsa);
+ ph->core->classes_jsa_fd = -1;
+ return false;
+ } else {
+ print_debug("opened %s\n", classes_jsa);
+ }
+
+ // read CDSFileMapHeaderBase from the file
+ memset(&header, 0, sizeof(CDSFileMapHeaderBase));
+ if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
+ != sizeof(CDSFileMapHeaderBase)) {
+ print_debug("can't read shared archive file map header from %s\n", classes_jsa);
+ close(fd);
+ return false;
+ }
+
+ // check file magic
+ if (header._magic != CDS_ARCHIVE_MAGIC) {
+ print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
+ classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
+ close(fd);
+ return false;
+ }
+
+ // check version
+ if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
+ print_debug("%s has wrong shared archive file version %d, expecting %d\n",
+ classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
+ close(fd);
+ return false;
+ }
+
+ ph->core->classes_jsa_fd = fd;
+ // add read-only maps from classes.jsa to the list of maps
+ for (m = 0; m < NUM_CDS_REGIONS; m++) {
+ if (header._space[m]._read_only) {
+ // With *some* linux versions, the core file doesn't include read-only mmap'ed
+ // files regions, so let's add them here. This is harmless if the core file also
+ // include these regions.
+ base = (uintptr_t) header._space[m]._addr._base;
+ // no need to worry about the fractional pages at-the-end.
+ // possible fractional pages are handled by core_read_data.
+ add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
+ base, (size_t) header._space[m]._used);
+ print_debug("added a share archive map at 0x%lx\n", base);
+ }
+ }
+ return true;
+ }
+ lib = lib->next;
+ }
+ return true;
+}
+
+#endif // defined(LINUX) || defined(__APPLE__)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.h Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,35 @@
+/*
+ * 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 _PS_CORE_COMMON_H_
+#define _PS_CORE_COMMON_H_
+
+map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr);
+map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
+ uintptr_t vaddr, size_t memsz);
+void core_release(struct ps_prochandle* ph);
+bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size);
+bool init_classsharing_workaround(struct ps_prochandle* ph);
+
+#endif // _PS_CORE_COMMON_H_
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java Wed Oct 16 11:23:46 2019 +0200
@@ -36,6 +36,7 @@
import javax.management.ObjectName;
import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
import org.graalvm.compiler.serviceprovider.ServiceProvider;
@@ -56,7 +57,7 @@
HotSpotGraalManagement nextDeferred;
@Override
- public void initialize(HotSpotGraalRuntime runtime) {
+ public void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config) {
if (bean == null) {
if (runtime.getManagement() != this) {
throw new IllegalArgumentException("Cannot initialize a second management object for runtime " + runtime.getName());
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java Wed Oct 16 11:23:46 2019 +0200
@@ -57,7 +57,7 @@
/**
* MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance.
*/
-final class HotSpotGraalRuntimeMBean implements DynamicMBean {
+public final class HotSpotGraalRuntimeMBean implements DynamicMBean {
/**
* The runtime instance to which this bean provides a management connection.
@@ -69,16 +69,16 @@
*/
private final ObjectName objectName;
- HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) {
+ public HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) {
this.objectName = objectName;
this.runtime = runtime;
}
- ObjectName getObjectName() {
+ public ObjectName getObjectName() {
return objectName;
}
- HotSpotGraalRuntime getRuntime() {
+ public HotSpotGraalRuntime getRuntime() {
return runtime;
}
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * 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
- * 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.graalvm.compiler.hotspot.management;
-
-import static java.lang.Thread.currentThread;
-
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-import org.graalvm.compiler.serviceprovider.ServiceProvider;
-import org.graalvm.compiler.serviceprovider.JMXService;
-
-import com.sun.management.ThreadMXBean;
-
-/**
- * Implementation of {@link JMXService} for JDK 13 and later.
- */
-@ServiceProvider(JMXService.class)
-public class JMXServiceProvider extends JMXService {
- private final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
-
- @Override
- protected long getThreadAllocatedBytes(long id) {
- return threadMXBean.getThreadAllocatedBytes(id);
- }
-
- @Override
- protected long getCurrentThreadCpuTime() {
- long[] times = threadMXBean.getThreadCpuTime(new long[]{currentThread().getId()});
- return times[0];
- }
-
- @Override
- protected boolean isThreadAllocatedMemorySupported() {
- return threadMXBean.isThreadAllocatedMemorySupported();
- }
-
- @Override
- protected boolean isCurrentThreadCpuTimeSupported() {
- return threadMXBean.isThreadCpuTimeSupported();
- }
-
- @Override
- protected List<String> getInputArguments() {
- return ManagementFactory.getRuntimeMXBean().getInputArguments();
- }
-}
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/package-info.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * JDK 11 and later versioned overlay for the {@code jdk.internal.vm.compiler.management} module.
- * This cannot be used in JDK 10 where {@code jdk.internal.vm.compiler.management} is a
- * non-upgradeable module.
- */
-
-
-package org.graalvm.compiler.hotspot.management;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java Wed Oct 16 11:23:46 2019 +0200
@@ -29,7 +29,7 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
/**
@@ -122,7 +122,7 @@
* @throws IllegalArgumentException if {@code input} cannot be decoded
*/
public static Map<String, Object> decode(byte[] input) {
- Map<String, Object> res = new HashMap<>();
+ Map<String, Object> res = new LinkedHashMap<>();
try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(input))) {
final int size = in.readInt();
for (int i = 0; i < size; i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Wed Oct 16 11:23:46 2019 +0200
@@ -25,6 +25,11 @@
package org.graalvm.compiler.asm.aarch64;
+import static jdk.vm.ci.aarch64.AArch64.CPU;
+import static jdk.vm.ci.aarch64.AArch64.rscratch1;
+import static jdk.vm.ci.aarch64.AArch64.rscratch2;
+import static jdk.vm.ci.aarch64.AArch64.sp;
+import static jdk.vm.ci.aarch64.AArch64.zr;
import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.BASE_REGISTER_ONLY;
import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.EXTENDED_REGISTER_OFFSET;
import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.IMMEDIATE_SCALED;
@@ -35,13 +40,6 @@
import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.NO_WORK;
import org.graalvm.compiler.asm.BranchTargetOutOfBoundsException;
-
-import static jdk.vm.ci.aarch64.AArch64.CPU;
-import static jdk.vm.ci.aarch64.AArch64.r8;
-import static jdk.vm.ci.aarch64.AArch64.r9;
-import static jdk.vm.ci.aarch64.AArch64.sp;
-import static jdk.vm.ci.aarch64.AArch64.zr;
-
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.debug.GraalError;
@@ -52,7 +50,7 @@
public class AArch64MacroAssembler extends AArch64Assembler {
- private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(r8), new ScratchRegister(r9)};
+ private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(rscratch1), new ScratchRegister(rscratch2)};
// Points to the next free scratch register
private int nextFreeScratchRegister = 0;
@@ -1310,6 +1308,20 @@
super.fmsub(size, dst, dst, d, n);
}
+ /**
+ * dst = src1 * src2 + src3.
+ *
+ * @param size register size.
+ * @param dst floating point register. May not be null.
+ * @param src1 floating point register. May not be null.
+ * @param src2 floating point register. May not be null.
+ * @param src3 floating point register. May not be null.
+ */
+ @Override
+ public void fmadd(int size, Register dst, Register src1, Register src2, Register src3) {
+ super.fmadd(size, dst, src1, src2, src3);
+ }
+
/* Branches */
/**
@@ -1367,32 +1379,32 @@
case 64: {
// Be careful with registers: it's possible that x, y, and dst are the same
// register.
- Register rscratch1 = sc1.getRegister();
- Register rscratch2 = sc2.getRegister();
- mul(64, rscratch1, x, y); // Result bits 0..63
- smulh(64, rscratch2, x, y); // Result bits 64..127
+ Register temp1 = sc1.getRegister();
+ Register temp2 = sc2.getRegister();
+ mul(64, temp1, x, y); // Result bits 0..63
+ smulh(64, temp2, x, y); // Result bits 64..127
// Top is pure sign ext
- subs(64, zr, rscratch2, rscratch1, ShiftType.ASR, 63);
+ subs(64, zr, temp2, temp1, ShiftType.ASR, 63);
// Copy all 64 bits of the result into dst
- mov(64, dst, rscratch1);
- mov(rscratch1, 0x80000000);
+ mov(64, dst, temp1);
+ mov(temp1, 0x80000000);
// Develop 0 (EQ), or 0x80000000 (NE)
- cmov(32, rscratch1, rscratch1, zr, ConditionFlag.NE);
- cmp(32, rscratch1, 1);
+ cmov(32, temp1, temp1, zr, ConditionFlag.NE);
+ cmp(32, temp1, 1);
// 0x80000000 - 1 => VS
break;
}
case 32: {
- Register rscratch1 = sc1.getRegister();
- smaddl(rscratch1, x, y, zr);
+ Register temp1 = sc1.getRegister();
+ smaddl(temp1, x, y, zr);
// Copy the low 32 bits of the result into dst
- mov(32, dst, rscratch1);
- subs(64, zr, rscratch1, rscratch1, ExtendType.SXTW, 0);
+ mov(32, dst, temp1);
+ subs(64, zr, temp1, temp1, ExtendType.SXTW, 0);
// NE => overflow
- mov(rscratch1, 0x80000000);
+ mov(temp1, 0x80000000);
// Develop 0 (EQ), or 0x80000000 (NE)
- cmov(32, rscratch1, rscratch1, zr, ConditionFlag.NE);
- cmp(32, rscratch1, 1);
+ cmov(32, temp1, temp1, zr, ConditionFlag.NE);
+ cmp(32, temp1, 1);
// 0x80000000 - 1 => VS
break;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Wed Oct 16 11:23:46 2019 +0200
@@ -229,9 +229,12 @@
}
private Value emitMultiplyAddSub(AArch64ArithmeticOp op, Value a, Value b, Value c) {
- assert isNumericInteger(a.getPlatformKind());
- assert isNumericInteger(b.getPlatformKind());
- assert isNumericInteger(c.getPlatformKind());
+ assert a.getPlatformKind() == b.getPlatformKind() && b.getPlatformKind() == c.getPlatformKind();
+ if (op == AArch64ArithmeticOp.ADD || op == AArch64ArithmeticOp.SUB) {
+ assert isNumericInteger(a.getPlatformKind());
+ } else if (op == AArch64ArithmeticOp.FADD) {
+ assert a.getPlatformKind() == AArch64Kind.SINGLE || a.getPlatformKind() == AArch64Kind.DOUBLE;
+ }
Variable result = getLIRGen().newVariable(LIRKind.combine(a, b, c));
AllocatableValue x = moveSp(asAllocatable(a));
@@ -447,6 +450,11 @@
}
@Override
+ public Value emitFusedMultiplyAdd(Value a, Value b, Value c) {
+ return emitMultiplyAddSub(AArch64ArithmeticOp.FADD, a, b, c);
+ }
+
+ @Override
public Value emitCountLeadingZeros(Value value) {
Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AArch64Kind.DWORD));
getLIRGen().append(new AArch64BitManipulationOp(getLIRGen(), CLZ, result, asAllocatable(value)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Wed Oct 16 11:23:46 2019 +0200
@@ -48,6 +48,10 @@
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
import org.graalvm.compiler.lir.aarch64.AArch64ArrayCompareToOp;
import org.graalvm.compiler.lir.aarch64.AArch64ArrayEqualsOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddLSEOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
import org.graalvm.compiler.lir.aarch64.AArch64Compare;
import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow;
@@ -59,10 +63,6 @@
import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
import org.graalvm.compiler.lir.aarch64.AArch64LIRFlagsVersioned;
import org.graalvm.compiler.lir.aarch64.AArch64Move;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddLSEOp;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
import org.graalvm.compiler.lir.aarch64.AArch64SpeculativeBarrier;
@@ -586,8 +586,15 @@
}
@Override
- public void emitZeroMemory(Value address, Value length) {
- // Value address is 8-byte aligned; Value length is multiple of 8.
- append(new AArch64ZeroMemoryOp(asAllocatable(address), asAllocatable(length), false, -1));
+ public void emitZeroMemory(Value address, Value length, boolean isAligned) {
+ emitZeroMemory(address, length, isAligned, false, -1);
+ }
+
+ protected final void emitZeroMemory(Value address, Value length, boolean isAligned, boolean useDcZva, int zvaLength) {
+ RegisterValue regAddress = AArch64.r0.asValue(address.getValueKind());
+ RegisterValue regLength = AArch64.r1.asValue(length.getValueKind());
+ emitMove(regAddress, address);
+ emitMove(regLength, length);
+ append(new AArch64ZeroMemoryOp(regAddress, regLength, isAligned, useDcZva, zvaLength));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LoweringProviderMixin.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LoweringProviderMixin.java Wed Oct 16 11:23:46 2019 +0200
@@ -35,7 +35,7 @@
}
@Override
- default int bulkZeroingStride() {
- return 8;
+ default boolean supportsBulkZeroing() {
+ return true;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Wed Oct 16 11:23:46 2019 +0200
@@ -687,7 +687,7 @@
}
@Override
- public void emitZeroMemory(Value address, Value length) {
+ public void emitZeroMemory(Value address, Value length, boolean isAligned) {
RegisterValue lengthReg = AMD64.rcx.asValue(length.getValueKind());
emitMove(lengthReg, length);
append(new AMD64ZeroMemoryOp(asAddressValue(address), lengthReg));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LoweringProviderMixin.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LoweringProviderMixin.java Wed Oct 16 11:23:46 2019 +0200
@@ -35,7 +35,7 @@
}
@Override
- default int bulkZeroingStride() {
- return 1;
+ default boolean supportsBulkZeroing() {
+ return true;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SparcLoweringProviderMixin.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SparcLoweringProviderMixin.java Wed Oct 16 11:23:46 2019 +0200
@@ -35,7 +35,7 @@
}
@Override
- default int bulkZeroingStride() {
- return 0;
+ default boolean supportsBulkZeroing() {
+ return false;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Wed Oct 16 11:23:46 2019 +0200
@@ -432,6 +432,16 @@
try {
Class<?> c = Class.forName(className, true, CheckGraalInvariants.class.getClassLoader());
classes.add(c);
+ } catch (UnsupportedClassVersionError e) {
+ // graal-test.jar can contain classes compiled for different Java versions
+ } catch (NoClassDefFoundError e) {
+ if (!e.getMessage().contains("Could not initialize class")) {
+ throw e;
+ } else {
+ // A second or later attempt to initialize a class
+ // results in this confusing error where the
+ // original cause of initialization failure is lost
+ }
} catch (Throwable t) {
tool.handleClassLoadingException(t);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphUtilOriginalValueTests.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,176 @@
+/*
+ * 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.graalvm.compiler.core.test;
+
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import org.graalvm.compiler.nodes.util.GraphUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+import jdk.vm.ci.code.BailoutException;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Unit tests derived from https://github.com/oracle/graal/pull/1690.
+ */
+public class GraphUtilOriginalValueTests extends CustomizedBytecodePatternTest {
+
+ static class LinkedNode {
+ LinkedNode next;
+ }
+
+ static class A extends LinkedNode {
+ }
+
+ static class B extends LinkedNode {
+ }
+
+ static class C extends LinkedNode {
+ }
+
+ public static Class<?> getLastClass(A a) {
+ LinkedNode current = a;
+ Class<?> currentKlass = null;
+ while (current != null) {
+ // This must not be folded to A.class
+ currentKlass = current.getClass();
+
+ current = current.next;
+ }
+ return currentKlass;
+ }
+
+ @Test
+ public void testGetClass() {
+ A a = new A();
+ a.next = new B();
+
+ test("getLastClass", a);
+ }
+
+ static final ConstantCallSite cs1 = init(A.class);
+ static final ConstantCallSite cs2 = init(B.class);
+ static final ConstantCallSite cs3 = init(C.class);
+
+ static ConstantCallSite init(Class<?> c) {
+ try {
+ return new ConstantCallSite(MethodHandles.lookup().unreflectConstructor(c.getDeclaredConstructor()));
+ } catch (Exception e) {
+ throw new InternalError(e);
+ }
+ }
+
+ public static boolean findTarget(MethodHandle key) {
+ ConstantCallSite cs = cs1;
+ while (cs != null) {
+ if (cs.getTarget() == key) {
+ return true;
+ }
+ if (cs == cs1) {
+ cs = cs2;
+ } else if (cs == cs2) {
+ cs = cs3;
+ } else {
+ cs = null;
+ }
+ }
+ return false;
+ }
+
+ @Test
+ public void testGetTarget() {
+ cs1.getTarget();
+ cs2.getTarget();
+ test("findTarget", cs3.getTarget());
+ }
+
+ @Override
+ protected byte[] generateClass(String internalClassName) {
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ cw.visit(52, ACC_SUPER | ACC_PUBLIC, internalClassName, null, "java/lang/Object", null);
+
+ String getDescriptor = "(Ljava/lang/Object;)V";
+ MethodVisitor m = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "unbalancedMonitors", getDescriptor, null, null);
+ Label loopHead = new Label();
+ Label end = new Label();
+ m.visitCode();
+
+ // @formatter:off
+ /*
+ * void unbalancedMonitors(Object o) {
+ * monitorenter(o);
+ * while (o.toString() != o) {
+ * monitorexit(o);
+ * o = o.toString();
+ * }
+ * }
+ */
+ // @formatter:on
+
+ m.visitVarInsn(ALOAD, 0);
+ m.visitInsn(MONITORENTER);
+ m.visitLabel(loopHead);
+ m.visitVarInsn(ALOAD, 0);
+ m.visitInsn(MONITOREXIT);
+ m.visitVarInsn(ALOAD, 0);
+ m.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);
+ m.visitVarInsn(ALOAD, 0);
+ m.visitJumpInsn(IF_ACMPEQ, end);
+ m.visitVarInsn(ALOAD, 0);
+ m.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);
+ m.visitVarInsn(ASTORE, 0);
+ m.visitJumpInsn(GOTO, loopHead);
+ m.visitLabel(end);
+ m.visitInsn(RETURN);
+ m.visitMaxs(2, 2);
+ m.visitEnd();
+
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ /**
+ * Tests that the use of {@link GraphUtil#originalValue} in parsing MONITOREXIT correctly
+ * detects unbalanced monitors.
+ */
+ @Test
+ public void testUnbalancedMonitors() throws ClassNotFoundException {
+ Class<?> testClass = getClass("UnbalancedMonitors");
+ ResolvedJavaMethod t1 = getResolvedJavaMethod(testClass, "unbalancedMonitors");
+ try {
+ parseForCompile(t1);
+ Assert.fail("expected a " + BailoutException.class.getName());
+ } catch (BailoutException e) {
+ String msg = e.getMessage();
+ Assert.assertTrue(msg, msg.contains("unbalanced monitors"));
+ }
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java Wed Oct 16 11:23:46 2019 +0200
@@ -87,8 +87,8 @@
} else if (holderQualified.equals("org.graalvm.compiler.hotspot.JVMCIVersionCheck") && caller.getName().equals("main")) {
// The main method in JVMCIVersionCheck is only called from the shell
return;
- } else if (packageName.startsWith("com.oracle.truffle") || packageName.startsWith("org.graalvm.polyglot")) {
- // Truffle and Polyglot do not depend on JVMCI so cannot use
+ } else if (packageName.startsWith("com.oracle.truffle") || packageName.startsWith("org.graalvm.polyglot") || packageName.startsWith("org.graalvm.home")) {
+ // Truffle and SDK do not depend on JVMCI so they cannot use
// Services.getSavedProperties()
return;
} else if (packageName.startsWith("com.oracle.svm")) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -40,7 +40,10 @@
import java.util.Objects;
import org.graalvm.graphio.GraphOutput;
import org.graalvm.graphio.GraphStructure;
+import org.graalvm.graphio.GraphTypes;
+import static org.junit.Assert.assertSame;
import org.junit.Test;
+import java.lang.reflect.Field;
public final class GraphOutputTest {
@@ -116,6 +119,18 @@
assertArrayEquals(expected.toByteArray(), embedded.toByteArray());
}
+ @Test
+ @SuppressWarnings({"static-method", "unchecked"})
+ public void testClassOfEnumValueWithImplementation() throws ClassNotFoundException, ReflectiveOperationException {
+ Class<? extends GraphTypes> defaultTypesClass = (Class<? extends GraphTypes>) Class.forName("org.graalvm.graphio.DefaultGraphTypes");
+ Field f = defaultTypesClass.getDeclaredField("DEFAULT");
+ f.setAccessible(true);
+ GraphTypes types = (GraphTypes) f.get(null);
+
+ Object clazz = types.enumClass(CustomEnum.ONE);
+ assertSame(CustomEnum.class, clazz);
+ }
+
private static ByteBuffer generateData(int size) {
ByteBuffer buffer = ByteBuffer.allocate(size);
for (int i = 0; i < size; i++) {
@@ -281,4 +296,20 @@
private static final class MockGraph {
}
+
+ private enum CustomEnum {
+ ONE() {
+ @Override
+ public String toString() {
+ return "one";
+ }
+ },
+
+ TWO() {
+ @Override
+ public String toString() {
+ return "two";
+ }
+ }
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -741,6 +741,7 @@
} else {
Object objectA = data.getObject(a, i);
Object objectB = data.getObject(b, i);
+ assert !isLambda(objectA) || !isLambda(objectB) : "lambdas are not permitted in fields of " + this.toString();
if (objectA != objectB) {
if (objectA != null && objectB != null) {
if (!deepEquals0(objectA, objectB)) {
@@ -755,6 +756,11 @@
return true;
}
+ private static boolean isLambda(Object obj) {
+ // This needs to be consistent with InnerClassLambdaMetafactory constructor.
+ return obj != null && obj.getClass().getSimpleName().contains("$$Lambda$");
+ }
+
public boolean isValid(Position pos, NodeClass<?> from, Edges fromEdges) {
if (this == from) {
return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java Wed Oct 16 11:23:46 2019 +0200
@@ -122,10 +122,6 @@
size = newSize;
}
- public boolean isList() {
- return true;
- }
-
protected abstract void update(T oldNode, T newNode);
public abstract Edges.Type getEdgesType();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java Wed Oct 16 11:23:46 2019 +0200
@@ -95,6 +95,9 @@
public void set(Node node, T value) {
assert check(node);
+ if (!node.isAlive()) {
+ throw new VerificationError("this node is not alive: " + node);
+ }
values[getNodeId(node)] = value;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Wed Oct 16 11:23:46 2019 +0200
@@ -192,7 +192,7 @@
replacements,
options);
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false,
- /* registerMathPlugins */true);
+ /* registerMathPlugins */true, /* emitJDK9StringSubstitutions */true, config.useFMAIntrinsics);
return plugins;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Wed Oct 16 11:23:46 2019 +0200
@@ -84,7 +84,6 @@
import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp;
import org.graalvm.compiler.lir.aarch64.AArch64RestoreRegistersOp;
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
-import org.graalvm.compiler.lir.aarch64.AArch64ZeroMemoryOp;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.options.OptionValues;
@@ -544,7 +543,7 @@
}
@Override
- public void emitZeroMemory(Value address, Value length) {
+ public void emitZeroMemory(Value address, Value length, boolean isAligned) {
int dczidValue = config.psrInfoDczidValue;
EnumSet<AArch64.Flag> flags = ((AArch64) target().arch).getFlags();
@@ -563,7 +562,6 @@
useDcZva = false;
}
- // Value address is 8-byte aligned; Value length is multiple of 8.
- append(new AArch64ZeroMemoryOp(asAllocatable(address), asAllocatable(length), useDcZva, zvaLength));
+ emitZeroMemory(address, length, isAligned, useDcZva, zvaLength);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -45,7 +45,10 @@
import static jdk.vm.ci.aarch64.AArch64.r25;
import static jdk.vm.ci.aarch64.AArch64.r26;
import static jdk.vm.ci.aarch64.AArch64.r28;
+import static jdk.vm.ci.aarch64.AArch64.r29;
import static jdk.vm.ci.aarch64.AArch64.r3;
+import static jdk.vm.ci.aarch64.AArch64.r30;
+import static jdk.vm.ci.aarch64.AArch64.r31;
import static jdk.vm.ci.aarch64.AArch64.r4;
import static jdk.vm.ci.aarch64.AArch64.r5;
import static jdk.vm.ci.aarch64.AArch64.r6;
@@ -96,12 +99,22 @@
public class AArch64HotSpotRegisterAllocationConfig extends RegisterAllocationConfig {
+ /**
+ * Excluding r27 is a temporary solution until we exclude r27 unconditionally at
+ * {@link jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig}.
+ *
+ * The underlying reason is that HotSpot does not intend to support r27 as an allocatable
+ * register. This register is excluded from callee-saved register at
+ * cpu/aarch64/sharedRuntime_aarch64.cpp:RegisterSaver::save_live_registers, and may lead to
+ * dereferencing unknown value from the stack at
+ * share/runtime/stackValue.cpp:StackValue::create_stack_value during deoptimization.
+ */
// @formatter:off
static final Register[] registerAllocationOrder = {
r0, r1, r2, r3, r4, r5, r6, r7,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
- r24, r25, r26, /* r27, */ r28, /* r29, r30, r31 */
+ r24, r25, r26, /* r27, */ r28, r29, r30, r31,
v0, v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -76,23 +76,22 @@
// Place reference slots at top and bottom of virtual frame
// with primitive slots in the middle. This tests that slot
// partitioning works.
+ AllocatableValue srcObject = gen.emitLoadConstant(objectLirKind, objectConstant);
for (int i = 0; i < numReferenceSlots / 2; i++) {
- AllocatableValue src = gen.emitLoadConstant(objectLirKind, objectConstant);
VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(objectLirKind);
slotList.add(slot);
- gen.emitMove(slot, src);
+ gen.emitMove(slot, srcObject);
}
+ AllocatableValue srcPrimitive = gen.emitLoadConstant(objectLirKind, primitiveConstant);
for (int i = 0; i < numPrimitiveSlots; i++) {
- AllocatableValue src = gen.emitLoadConstant(objectLirKind, primitiveConstant);
VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(primitiveLirKind);
slotList.add(slot);
- gen.emitMove(slot, src);
+ gen.emitMove(slot, srcPrimitive);
}
for (int i = numReferenceSlots / 2; i < numReferenceSlots; i++) {
- AllocatableValue src = gen.emitLoadConstant(objectLirKind, objectConstant);
VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(objectLirKind);
slotList.add(slot);
- gen.emitMove(slot, src);
+ gen.emitMove(slot, srcObject);
}
slots = slotList.toArray(new AllocatableValue[slotList.size()]);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Wed Oct 16 11:23:46 2019 +0200
@@ -64,6 +64,7 @@
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.sparc.SPARC;
/**
* Checks the intrinsics implemented by Graal against the set of intrinsics declared by HotSpot. The
@@ -375,7 +376,7 @@
add(ignore,
"java/lang/Math.fma(DDD)D",
"java/lang/Math.fma(FFF)F");
- } else if (!(arch instanceof AMD64)) {
+ } else if (arch instanceof SPARC) {
add(toBeInvestigated,
"java/lang/Math.fma(DDD)D",
"java/lang/Math.fma(FFF)F");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java Wed Oct 16 11:23:46 2019 +0200
@@ -25,8 +25,6 @@
package org.graalvm.compiler.hotspot.test;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPEC;
-
import java.lang.reflect.Method;
import org.graalvm.compiler.core.test.GraalCompilerTest;
@@ -75,9 +73,27 @@
return graph;
}
+ private static String getMiscPackage() {
+ if (JavaVersionUtil.JAVA_SPEC <= 8) {
+ return "sun.misc";
+ }
+ try {
+ String miscPackage = "jdk.internal.access";
+ Class.forName(miscPackage + ".SharedSecrets");
+ return miscPackage;
+ } catch (ClassNotFoundException e) {
+ try {
+ String miscPackage = "jdk.internal.misc";
+ Class.forName(miscPackage + ".SharedSecrets");
+ return miscPackage;
+ } catch (ClassNotFoundException ex) {
+ }
+ throw new AssertionError(e);
+ }
+ }
+
private static Object getConstantPoolForObject() {
- String miscPackage = JavaVersionUtil.JAVA_SPEC <= 8 ? "sun.misc"
- : (JavaVersionUtil.JAVA_SPEC <= 11 ? "jdk.internal.misc" : "jdk.internal.access");
+ String miscPackage = getMiscPackage();
try {
Class<?> sharedSecretsClass = Class.forName(miscPackage + ".SharedSecrets");
Class<?> javaLangAccessClass = Class.forName(miscPackage + ".JavaLangAccess");
@@ -112,8 +128,7 @@
* This test uses some non-public API.
*/
private static void addExports(Class<?> c) {
- String packageName = JAVA_SPEC <= 11 ? "jdk.internal.misc" : "jdk.internal.access";
- ModuleSupport.exportPackageTo(String.class, packageName, c);
+ ModuleSupport.exportPackageTo(String.class, getMiscPackage(), c);
ModuleSupport.exportPackageTo(String.class, "jdk.internal.reflect", c);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Wed Oct 16 11:23:46 2019 +0200
@@ -321,6 +321,7 @@
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 final int jniEnvironmentOffset = getFieldOffset("JavaThread::_jni_environment", Integer.class, "JNIEnv", Integer.MIN_VALUE);
public boolean requiresReservedStackCheck(List<ResolvedJavaMethod> methods) {
if (enableStackReservedZoneAddress != 0 && methods != null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -35,7 +35,7 @@
* Completes the initialization of this registration by recording the
* {@link HotSpotGraalRuntime} the MBean will provide an JMX interface to.
*/
- void initialize(HotSpotGraalRuntime runtime);
+ void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config);
/**
* Polls this registration to see if the MBean is registered in a MBean server.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Wed Oct 16 11:23:46 2019 +0200
@@ -35,6 +35,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
@@ -97,6 +98,10 @@
public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
private static final boolean IS_AOT = Boolean.parseBoolean(Services.getSavedProperties().get("com.oracle.graalvm.isaot"));
+ /**
+ * A factory for {@link HotSpotGraalManagementRegistration} injected by {@code LibGraalFeature}.
+ */
+ private static final Supplier<HotSpotGraalManagementRegistration> AOT_INJECTED_MANAGEMENT = null;
private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAccess) {
assert metaAccess.getArrayIndexScale(JavaKind.Byte) == 1;
@@ -165,12 +170,12 @@
compilerConfigurationName = compilerConfigurationFactory.getName();
if (IS_AOT) {
- management = null;
+ management = AOT_INJECTED_MANAGEMENT == null ? null : AOT_INJECTED_MANAGEMENT.get();
} else {
management = GraalServices.loadSingle(HotSpotGraalManagementRegistration.class, false);
- if (management != null) {
- management.initialize(this);
- }
+ }
+ if (management != null) {
+ management.initialize(this, config);
}
BackendMap backendMap = compilerConfigurationFactory.createBackendMap();
@@ -292,13 +297,15 @@
HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) compilable).getDeclaringClass();
if (type instanceof HotSpotResolvedJavaType) {
Class<?> clazz = runtime().getMirror(type);
- try {
- ClassLoader cl = clazz.getClassLoader();
- if (cl != null) {
- loaders.add(cl);
+ if (clazz != null) {
+ try {
+ ClassLoader cl = clazz.getClassLoader();
+ if (cl != null) {
+ loaders.add(cl);
+ }
+ } catch (SecurityException e) {
+ // This loader can obviously not be used for resolving class names
}
- } catch (SecurityException e) {
- // This loader can obviously not be used for resolving class names
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Wed Oct 16 11:23:46 2019 +0200
@@ -43,7 +43,7 @@
*/
public final class JVMCIVersionCheck {
- private static final Version JVMCI8_MIN_VERSION = new Version3(19, 2, 1);
+ private static final Version JVMCI8_MIN_VERSION = new Version3(19, 3, 2);
public interface Version {
boolean isLessThan(Version other);
@@ -230,6 +230,17 @@
failVersionCheck(props, exitOnFailure, "Could not parse the JDK 11 early access build number from java.vm.version property: %s.%n", vmVersion);
return;
}
+ } else if (vmVersion.contains("-jvmci-")) {
+ // A "labsjdk"
+ Version v = Version.parse(vmVersion);
+ if (v != null) {
+ if (v.isLessThan(minVersion)) {
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion);
+ }
+ return;
+ }
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+ "Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
} else {
// Graal is compatible with all JDK versions as of 11 GA.
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Oct 16 11:23:46 2019 +0200
@@ -254,7 +254,7 @@
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode callSite = receiver.get();
- ValueNode folded = CallSiteTargetNode.tryFold(GraphUtil.originalValue(callSite), b.getMetaAccess(), b.getAssumptions());
+ ValueNode folded = CallSiteTargetNode.tryFold(GraphUtil.originalValue(callSite, true), b.getMetaAccess(), b.getAssumptions());
if (folded != null) {
b.addPush(JavaKind.Object, folded);
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Wed Oct 16 11:23:46 2019 +0200
@@ -359,12 +359,12 @@
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
- @ConstantParameter int bulkZeroingStride,
+ @ConstantParameter boolean supportsBulkZeroing,
@ConstantParameter Counters counters) {
// Primitive array types are eagerly pre-resolved. We can use a floating load.
KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
- emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, bulkZeroingStride, counters);
+ emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, supportsBulkZeroing, counters);
}
@Snippet
@@ -378,12 +378,12 @@
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
- @ConstantParameter int bulkZeroingStride,
+ @ConstantParameter boolean supportsBulkZeroing,
@ConstantParameter Counters counters) {
// Array type would be resolved by dominating resolution.
KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
- emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, bulkZeroingStride, counters);
+ emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, supportsBulkZeroing, counters);
}
@Snippet
@@ -397,7 +397,7 @@
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
- @ConstantParameter int bulkZeroingStride,
+ @ConstantParameter boolean supportsBulkZeroing,
@ConstantParameter Counters counters) {
Object result = allocateArrayImpl(hub,
length,
@@ -408,7 +408,7 @@
emitMemoryBarrier, threadRegister,
maybeUnroll,
typeContext,
- bulkZeroingStride,
+ supportsBulkZeroing,
counters);
return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
}
@@ -432,7 +432,7 @@
Register threadRegister,
boolean maybeUnroll,
String typeContext,
- int bulkZeroingStride,
+ boolean supportsBulkZeroing,
Counters counters) {
Object result;
long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize);
@@ -448,7 +448,7 @@
if (theCounters != null && theCounters.arrayLoopInit != null) {
theCounters.arrayLoopInit.inc();
}
- result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, bulkZeroingStride, counters);
+ result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, supportsBulkZeroing, counters);
} else {
result = newArrayStub(hub, length);
}
@@ -513,11 +513,11 @@
@ConstantParameter Register threadRegister,
@ConstantParameter JavaKind knownElementKind,
@ConstantParameter int knownLayoutHelper,
- @ConstantParameter int bulkZeroingStride,
+ @ConstantParameter boolean supportsBulkZeroing,
Word prototypeMarkWord,
@ConstantParameter Counters counters) {
Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, emitMemoryBarrier, threadRegister, knownElementKind,
- knownLayoutHelper, bulkZeroingStride, prototypeMarkWord, counters);
+ knownLayoutHelper, supportsBulkZeroing, prototypeMarkWord, counters);
return result;
}
@@ -529,7 +529,7 @@
Register threadRegister,
JavaKind knownElementKind,
int knownLayoutHelper,
- int bulkZeroingStride,
+ boolean supportsBulkZeroing,
Word prototypeMarkWord,
Counters counters) {
/*
@@ -574,7 +574,7 @@
int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
- emitMemoryBarrier, threadRegister, false, "dynamic type", bulkZeroingStride, counters);
+ emitMemoryBarrier, threadRegister, false, "dynamic type", supportsBulkZeroing, counters);
return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
}
@@ -627,16 +627,16 @@
* @param endOffset offset to stop zeroing (exclusive). May not be word aligned.
* @param isEndOffsetConstant is {@code endOffset} known to be constant in the snippet
* @param manualUnroll maximally unroll zeroing
- * @param bulkZeroingStride stride of bulk zeroing supported by the backend
+ * @param supportsBulkZeroing whether bulk zeroing is supported by the backend
*/
private static void zeroMemory(Word memory, int startOffset, long endOffset, boolean isEndOffsetConstant, boolean manualUnroll,
- int bulkZeroingStride, Counters counters) {
- fillMemory(0, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, bulkZeroingStride, counters);
+ boolean supportsBulkZeroing, Counters counters) {
+ fillMemory(0, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, supportsBulkZeroing, counters);
}
- private static void fillMemory(long value, Word memory, int startOffset, long offsetLimit, boolean constantOffsetLimit, boolean manualUnroll,
- int bulkZeroingStride, Counters counters) {
- ReplacementsUtil.runtimeAssert((offsetLimit & 0x7) == 0, "unaligned object size");
+ private static void fillMemory(long value, Word memory, int startOffset, long endOffset, boolean constantOffsetLimit, boolean manualUnroll,
+ boolean supportsBulkZeroing, Counters counters) {
+ ReplacementsUtil.runtimeAssert((endOffset & 0x7) == 0, "unaligned object size");
int offset = startOffset;
if ((offset & 0x7) != 0) {
memory.writeInt(offset, (int) value, LocationIdentity.init());
@@ -644,7 +644,7 @@
}
ReplacementsUtil.runtimeAssert((offset & 0x7) == 0, "unaligned offset");
Counters theCounters = counters;
- if (manualUnroll && ((offsetLimit - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
+ if (manualUnroll && ((endOffset - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
ReplacementsUtil.staticAssert(!constantOffsetLimit, "size shouldn't be constant at instantiation time");
// This case handles arrays of constant length. Instead of having a snippet variant for
// each length, generate a chain of stores of maximum length. Once it's inlined the
@@ -655,7 +655,7 @@
explodeLoop();
for (int i = 0; i < MAX_UNROLLED_OBJECT_ZEROING_STORES; i++, offset += 8) {
- if (offset == offsetLimit) {
+ if (offset == endOffset) {
break;
}
memory.initializeLong(offset, value, LocationIdentity.init());
@@ -663,13 +663,13 @@
} else {
// Use Word instead of int to avoid extension to long in generated code
Word off = WordFactory.signed(offset);
- if (bulkZeroingStride > 0 && value == 0 && probability(SLOW_PATH_PROBABILITY, (offsetLimit - offset) >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
+ if (supportsBulkZeroing && value == 0 && probability(SLOW_PATH_PROBABILITY, (endOffset - offset) >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
if (theCounters != null && theCounters.instanceBulkInit != null) {
theCounters.instanceBulkInit.inc();
}
- ZeroMemoryNode.zero(memory.add(off), offsetLimit - offset, LocationIdentity.init());
+ ZeroMemoryNode.zero(memory.add(off), endOffset - offset, true, LocationIdentity.init());
} else {
- if (constantOffsetLimit && ((offsetLimit - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
+ if (constantOffsetLimit && ((endOffset - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
if (theCounters != null && theCounters.instanceSeqInit != null) {
theCounters.instanceSeqInit.inc();
}
@@ -679,7 +679,7 @@
theCounters.instanceLoopInit.inc();
}
}
- for (; off.rawValue() < offsetLimit; off = off.add(8)) {
+ for (; off.rawValue() < endOffset; off = off.add(8)) {
memory.initializeLong(off, value, LocationIdentity.init());
}
}
@@ -703,7 +703,7 @@
* @param manualUnroll maximally unroll zeroing
*/
private static void fillWithGarbage(Word memory, int startOffset, long endOffset, boolean isEndOffsetConstant, boolean manualUnroll, Counters counters) {
- fillMemory(0xfefefefefefefefeL, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, 0, counters);
+ fillMemory(0xfefefefefefefefeL, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, false, counters);
}
/**
@@ -720,7 +720,7 @@
Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
initializeObjectHeader(memory, prototypeMarkWord, hub);
if (fillContents) {
- zeroMemory(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, 0, counters);
+ zeroMemory(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, false, counters);
} else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
fillWithGarbage(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, counters);
}
@@ -767,7 +767,7 @@
boolean fillContents,
boolean emitMemoryBarrier,
boolean maybeUnroll,
- int bulkZeroingStride,
+ boolean supportsBulkZeroing,
Counters counters) {
memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init());
/*
@@ -776,7 +776,7 @@
*/
initializeObjectHeader(memory, prototypeMarkWord, hub);
if (fillContents) {
- zeroMemory(memory, headerSize, allocationSize, false, maybeUnroll, bulkZeroingStride, counters);
+ zeroMemory(memory, headerSize, allocationSize, false, maybeUnroll, supportsBulkZeroing, counters);
} else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
fillWithGarbage(memory, headerSize, allocationSize, false, maybeUnroll, counters);
}
@@ -897,7 +897,7 @@
args.addConst("threadRegister", registers.getThreadRegister());
args.addConst("maybeUnroll", length.isConstant());
args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : "");
- args.addConst("bulkZeroingStride", tool.getLowerer().bulkZeroingStride());
+ args.addConst("supportsBulkZeroing", tool.getLowerer().supportsBulkZeroing());
args.addConst("counters", counters);
SnippetTemplate template = template(newArrayNode, args);
graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
@@ -941,7 +941,7 @@
} else {
args.addConst("knownLayoutHelper", 0);
}
- args.addConst("bulkZeroingStride", tool.getLowerer().bulkZeroingStride());
+ args.addConst("supportsBulkZeroing", tool.getLowerer().supportsBulkZeroing());
args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord());
args.addConst("counters", counters);
SnippetTemplate template = template(newArrayNode, args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java Wed Oct 16 11:23:46 2019 +0200
@@ -26,27 +26,108 @@
import static org.graalvm.compiler.bytecode.Bytecodes.AALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.AASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ACONST_NULL;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_3;
import static org.graalvm.compiler.bytecode.Bytecodes.ANEWARRAY;
import static org.graalvm.compiler.bytecode.Bytecodes.ARETURN;
import static org.graalvm.compiler.bytecode.Bytecodes.ARRAYLENGTH;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_3;
import static org.graalvm.compiler.bytecode.Bytecodes.ATHROW;
import static org.graalvm.compiler.bytecode.Bytecodes.BALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.BASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.BIPUSH;
+import static org.graalvm.compiler.bytecode.Bytecodes.BREAKPOINT;
import static org.graalvm.compiler.bytecode.Bytecodes.CALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.CASTORE;
import static org.graalvm.compiler.bytecode.Bytecodes.CHECKCAST;
+import static org.graalvm.compiler.bytecode.Bytecodes.D2F;
+import static org.graalvm.compiler.bytecode.Bytecodes.D2I;
+import static org.graalvm.compiler.bytecode.Bytecodes.D2L;
+import static org.graalvm.compiler.bytecode.Bytecodes.DADD;
import static org.graalvm.compiler.bytecode.Bytecodes.DALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.DASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCMPG;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCMPL;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCONST_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DDIV;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.DMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.DNEG;
+import static org.graalvm.compiler.bytecode.Bytecodes.DREM;
import static org.graalvm.compiler.bytecode.Bytecodes.DRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSUB;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X2;
+import static org.graalvm.compiler.bytecode.Bytecodes.F2D;
+import static org.graalvm.compiler.bytecode.Bytecodes.F2I;
+import static org.graalvm.compiler.bytecode.Bytecodes.F2L;
+import static org.graalvm.compiler.bytecode.Bytecodes.FADD;
import static org.graalvm.compiler.bytecode.Bytecodes.FALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.FASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCMPG;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCMPL;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCONST_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCONST_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.FDIV;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.FMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.FNEG;
+import static org.graalvm.compiler.bytecode.Bytecodes.FREM;
import static org.graalvm.compiler.bytecode.Bytecodes.FRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSUB;
import static org.graalvm.compiler.bytecode.Bytecodes.GETFIELD;
import static org.graalvm.compiler.bytecode.Bytecodes.GETSTATIC;
import static org.graalvm.compiler.bytecode.Bytecodes.GOTO;
import static org.graalvm.compiler.bytecode.Bytecodes.GOTO_W;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2B;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2C;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2D;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2F;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2L;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2S;
+import static org.graalvm.compiler.bytecode.Bytecodes.IADD;
import static org.graalvm.compiler.bytecode.Bytecodes.IALOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.IAND;
import static org.graalvm.compiler.bytecode.Bytecodes.IASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_4;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_5;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_M1;
import static org.graalvm.compiler.bytecode.Bytecodes.IDIV;
import static org.graalvm.compiler.bytecode.Bytecodes.IFEQ;
import static org.graalvm.compiler.bytecode.Bytecodes.IFGE;
@@ -64,33 +145,88 @@
import static org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPLE;
import static org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPLT;
import static org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPNE;
+import static org.graalvm.compiler.bytecode.Bytecodes.IINC;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.IMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.INEG;
+import static org.graalvm.compiler.bytecode.Bytecodes.INSTANCEOF;
import static org.graalvm.compiler.bytecode.Bytecodes.INVOKEDYNAMIC;
import static org.graalvm.compiler.bytecode.Bytecodes.INVOKEINTERFACE;
import static org.graalvm.compiler.bytecode.Bytecodes.INVOKESPECIAL;
import static org.graalvm.compiler.bytecode.Bytecodes.INVOKESTATIC;
import static org.graalvm.compiler.bytecode.Bytecodes.INVOKEVIRTUAL;
+import static org.graalvm.compiler.bytecode.Bytecodes.IOR;
import static org.graalvm.compiler.bytecode.Bytecodes.IREM;
import static org.graalvm.compiler.bytecode.Bytecodes.IRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISHL;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISUB;
+import static org.graalvm.compiler.bytecode.Bytecodes.IUSHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.IXOR;
import static org.graalvm.compiler.bytecode.Bytecodes.JSR;
import static org.graalvm.compiler.bytecode.Bytecodes.JSR_W;
+import static org.graalvm.compiler.bytecode.Bytecodes.L2D;
+import static org.graalvm.compiler.bytecode.Bytecodes.L2F;
+import static org.graalvm.compiler.bytecode.Bytecodes.L2I;
+import static org.graalvm.compiler.bytecode.Bytecodes.LADD;
import static org.graalvm.compiler.bytecode.Bytecodes.LALOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.LAND;
import static org.graalvm.compiler.bytecode.Bytecodes.LASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.LCMP;
+import static org.graalvm.compiler.bytecode.Bytecodes.LCONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.LCONST_1;
import static org.graalvm.compiler.bytecode.Bytecodes.LDC;
import static org.graalvm.compiler.bytecode.Bytecodes.LDC2_W;
import static org.graalvm.compiler.bytecode.Bytecodes.LDC_W;
import static org.graalvm.compiler.bytecode.Bytecodes.LDIV;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.LMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.LNEG;
import static org.graalvm.compiler.bytecode.Bytecodes.LOOKUPSWITCH;
+import static org.graalvm.compiler.bytecode.Bytecodes.LOR;
import static org.graalvm.compiler.bytecode.Bytecodes.LREM;
import static org.graalvm.compiler.bytecode.Bytecodes.LRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSHL;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSUB;
+import static org.graalvm.compiler.bytecode.Bytecodes.LUSHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.LXOR;
+import static org.graalvm.compiler.bytecode.Bytecodes.MONITORENTER;
+import static org.graalvm.compiler.bytecode.Bytecodes.MONITOREXIT;
import static org.graalvm.compiler.bytecode.Bytecodes.MULTIANEWARRAY;
import static org.graalvm.compiler.bytecode.Bytecodes.NEW;
+import static org.graalvm.compiler.bytecode.Bytecodes.NEWARRAY;
+import static org.graalvm.compiler.bytecode.Bytecodes.NOP;
+import static org.graalvm.compiler.bytecode.Bytecodes.POP;
+import static org.graalvm.compiler.bytecode.Bytecodes.POP2;
import static org.graalvm.compiler.bytecode.Bytecodes.PUTFIELD;
import static org.graalvm.compiler.bytecode.Bytecodes.PUTSTATIC;
import static org.graalvm.compiler.bytecode.Bytecodes.RET;
import static org.graalvm.compiler.bytecode.Bytecodes.RETURN;
import static org.graalvm.compiler.bytecode.Bytecodes.SALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.SASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.SIPUSH;
+import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
import static org.graalvm.compiler.bytecode.Bytecodes.TABLESWITCH;
+import static org.graalvm.compiler.bytecode.Bytecodes.WIDE;
import static org.graalvm.compiler.core.common.GraalOptions.SupportJsrBytecodes;
import java.util.ArrayDeque;
@@ -111,6 +247,7 @@
import org.graalvm.compiler.bytecode.Bytecodes;
import org.graalvm.compiler.core.common.PermanentBailoutException;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.BytecodeFrame;
@@ -159,7 +296,7 @@
int id;
final int startBci;
- int endBci;
+ int endBci; // The bci of the last bytecode in the block
private boolean isExceptionEntry;
private boolean isLoopHeader;
int loopId;
@@ -698,7 +835,9 @@
case SALOAD:
case ARRAYLENGTH:
case CHECKCAST:
+ case INSTANCEOF:
case NEW:
+ case NEWARRAY:
case ANEWARRAY:
case MULTIANEWARRAY:
case PUTSTATIC:
@@ -707,7 +846,8 @@
case GETFIELD:
case LDC:
case LDC_W:
- case LDC2_W: {
+ case LDC2_W:
+ case MONITORENTER: {
/*
* All bytecodes that can trigger lazy class initialization via a
* ClassInitializationPlugin (allocations, static field access) must be listed
@@ -720,7 +860,150 @@
addSuccessor(blockMap, bci, makeBlock(blockMap, stream.nextBCI()));
addSuccessor(blockMap, bci, handler);
}
+ break;
}
+
+ case NOP:
+ case ACONST_NULL:
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ case LCONST_0:
+ case LCONST_1:
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ case DCONST_0:
+ case DCONST_1:
+ case BIPUSH:
+ case SIPUSH:
+ case ILOAD:
+ case LLOAD:
+ case FLOAD:
+ case DLOAD:
+ case ALOAD:
+ case ILOAD_0:
+ case ILOAD_1:
+ case ILOAD_2:
+ case ILOAD_3:
+ case LLOAD_0:
+ case LLOAD_1:
+ case LLOAD_2:
+ case LLOAD_3:
+ case FLOAD_0:
+ case FLOAD_1:
+ case FLOAD_2:
+ case FLOAD_3:
+ case DLOAD_0:
+ case DLOAD_1:
+ case DLOAD_2:
+ case DLOAD_3:
+ case ALOAD_0:
+ case ALOAD_1:
+ case ALOAD_2:
+ case ALOAD_3:
+ case ISTORE:
+ case LSTORE:
+ case FSTORE:
+ case DSTORE:
+ case ASTORE:
+ case ISTORE_0:
+ case ISTORE_1:
+ case ISTORE_2:
+ case ISTORE_3:
+ case LSTORE_0:
+ case LSTORE_1:
+ case LSTORE_2:
+ case LSTORE_3:
+ case FSTORE_0:
+ case FSTORE_1:
+ case FSTORE_2:
+ case FSTORE_3:
+ case DSTORE_0:
+ case DSTORE_1:
+ case DSTORE_2:
+ case DSTORE_3:
+ case ASTORE_0:
+ case ASTORE_1:
+ case ASTORE_2:
+ case ASTORE_3:
+ case POP:
+ case POP2:
+ case DUP:
+ case DUP_X1:
+ case DUP_X2:
+ case DUP2:
+ case DUP2_X1:
+ case DUP2_X2:
+ case SWAP:
+ case IADD:
+ case LADD:
+ case FADD:
+ case DADD:
+ case ISUB:
+ case LSUB:
+ case FSUB:
+ case DSUB:
+ case IMUL:
+ case LMUL:
+ case FMUL:
+ case DMUL:
+ case FDIV:
+ case DDIV:
+ case FREM:
+ case DREM:
+ case INEG:
+ case LNEG:
+ case FNEG:
+ case DNEG:
+ case ISHL:
+ case LSHL:
+ case ISHR:
+ case LSHR:
+ case IUSHR:
+ case LUSHR:
+ case IAND:
+ case LAND:
+ case IOR:
+ case LOR:
+ case IXOR:
+ case LXOR:
+ case IINC:
+ case I2L:
+ case I2F:
+ case I2D:
+ case L2I:
+ case L2F:
+ case L2D:
+ case F2I:
+ case F2L:
+ case F2D:
+ case D2I:
+ case D2L:
+ case D2F:
+ case I2B:
+ case I2C:
+ case I2S:
+ case LCMP:
+ case FCMPL:
+ case FCMPG:
+ case DCMPL:
+ case DCMPG:
+ case MONITOREXIT:
+ // All stack manipulation, comparison, conversion and arithmetic operators
+ // except for idiv and irem can't throw exceptions so the don't need to connect
+ // exception edges. MONITOREXIT can't throw exceptions in the context of
+ // compiled code because of the structured locking requirement in the parser.
+ break;
+
+ case WIDE:
+ case BREAKPOINT:
+ default:
+ throw new GraalError("Unhandled bytecode");
}
stream.next();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Wed Oct 16 11:23:46 2019 +0200
@@ -361,6 +361,7 @@
import org.graalvm.compiler.nodes.calc.ConditionalNode;
import org.graalvm.compiler.nodes.calc.FloatConvertNode;
import org.graalvm.compiler.nodes.calc.FloatDivNode;
+import org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode;
import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
@@ -370,7 +371,6 @@
import org.graalvm.compiler.nodes.calc.MulNode;
import org.graalvm.compiler.nodes.calc.NarrowNode;
import org.graalvm.compiler.nodes.calc.NegateNode;
-import org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode;
import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
import org.graalvm.compiler.nodes.calc.OrNode;
import org.graalvm.compiler.nodes.calc.RemNode;
@@ -2706,8 +2706,10 @@
}
MonitorIdNode monitorId = frameState.peekMonitorId();
ValueNode lockedObject = frameState.popLock();
- if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
- throw bailout(String.format("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject)));
+ ValueNode originalLockedObject = GraphUtil.originalValue(lockedObject, false);
+ ValueNode originalX = GraphUtil.originalValue(x, false);
+ if (originalLockedObject != originalX) {
+ throw bailout(String.format("unbalanced monitors: mismatch at monitorexit, %s != %s", originalLockedObject, originalX));
}
MonitorExitNode monitorExit = append(new MonitorExitNode(lockedObject, monitorId, escapedValue));
monitorExit.setStateAfter(createFrameState(bci, monitorExit));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Wed Oct 16 11:23:46 2019 +0200
@@ -35,6 +35,7 @@
import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
import static org.graalvm.compiler.nodes.FrameState.TWO_SLOT_MARKER;
+import static org.graalvm.compiler.nodes.util.GraphUtil.originalValue;
import java.util.ArrayList;
import java.util.Arrays;
@@ -70,7 +71,6 @@
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.SideEffectsState;
import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
-import org.graalvm.compiler.nodes.util.GraphUtil;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.meta.Assumptions;
@@ -384,38 +384,54 @@
return new FrameStateBuilder(this);
}
- public boolean isCompatibleWith(FrameStateBuilder other) {
+ private String incompatibilityErrorMessage(String reason, FrameStateBuilder other) {
+ return String.format("Frame states being merged are incompatible: %s%n This frame state: %s%nOther frame state: %s%nParser context: %s", reason, this, other, parser);
+ }
+
+ /**
+ * Checks invariants that must hold when merging {@code other} into this frame state.
+ *
+ * @param other
+ * @throws PermanentBailoutException if the frame states are incompatible with respect to their
+ * locked objects. This indicates bytecode that has unstructured or unbalanced
+ * locks.
+ * @throws GraalError if the frame states are incompatible in terms of {@link #rethrowException}
+ * or stack slots
+ */
+ public void checkCompatibleWith(FrameStateBuilder other) {
assert code.equals(other.code) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method";
assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds";
if (rethrowException != other.rethrowException) {
- return false;
+ throw new GraalError(incompatibilityErrorMessage("mismatch in rethrowException flag", other));
}
if (stackSize() != other.stackSize()) {
- return false;
+ throw new GraalError(incompatibilityErrorMessage("mismatch in stack sizes", other));
}
for (int i = 0; i < stackSize(); i++) {
ValueNode x = stack[i];
ValueNode y = other.stack[i];
assert x != null && y != null;
if (x != y && (x == TWO_SLOT_MARKER || x.isDeleted() || y == TWO_SLOT_MARKER || y.isDeleted() || x.getStackKind() != y.getStackKind())) {
- return false;
+ throw new GraalError(incompatibilityErrorMessage("mismatch in stack types", other));
}
}
if (lockedObjects.length != other.lockedObjects.length) {
- return false;
+ throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - locked objects do not match", other));
}
for (int i = 0; i < lockedObjects.length; i++) {
- if (GraphUtil.originalValue(lockedObjects[i]) != GraphUtil.originalValue(other.lockedObjects[i]) || monitorIds[i] != other.monitorIds[i]) {
- throw new PermanentBailoutException("unbalanced monitors");
+ if (originalValue(lockedObjects[i], false) != originalValue(other.lockedObjects[i], false)) {
+ throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - locked objects do not match", other));
+ }
+ if (monitorIds[i] != other.monitorIds[i]) {
+ throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - monitors do not match", other));
}
}
- return true;
}
public void merge(AbstractMergeNode block, FrameStateBuilder other) {
- GraalError.guarantee(isCompatibleWith(other), "stacks do not match on merge; bytecodes would not verify:%nexpect: %s%nactual: %s", block, other);
+ checkCompatibleWith(other);
for (int i = 0; i < localsSize(); i++) {
locals[i] = merge(locals[i], other.locals[i], block);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Field_set02.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Field_set02.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -24,10 +24,11 @@
package org.graalvm.compiler.jtt.reflect;
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.jtt.JTTTest;
+import org.graalvm.compiler.options.OptionValues;
import org.junit.Test;
-import org.graalvm.compiler.jtt.JTTTest;
-
/*
*/
public class Field_set02 extends JTTTest {
@@ -76,7 +77,13 @@
@Test
public void run0() throws Throwable {
- runTest("test", 0);
+ try {
+ runTest("test", 0);
+ } catch (AssertionError e) {
+ System.err.println(e);
+ System.err.println("object.byteField == " + object.byteField);
+ runTest(new OptionValues(getInitialOptions(), DebugOptions.Dump, ":2"), "test", 0);
+ }
}
@Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticOp.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticOp.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -481,7 +481,7 @@
*/
public MultiplyAddSubOp(AArch64ArithmeticOp op, AllocatableValue result, AllocatableValue src1, AllocatableValue src2, AllocatableValue src3) {
super(TYPE);
- assert op == ADD || op == SUB;
+ assert op == ADD || op == SUB || op == FADD;
this.op = op;
this.result = result;
this.src1 = src1;
@@ -499,6 +499,9 @@
case SUB:
masm.msub(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
break;
+ case FADD:
+ masm.fmadd(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
+ break;
default:
throw GraalError.shouldNotReachHere();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ZeroMemoryOp.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ZeroMemoryOp.java Wed Oct 16 11:23:46 2019 +0200
@@ -32,6 +32,7 @@
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
+import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -39,7 +40,7 @@
import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.Register;
-import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
/**
* Zero a chunk of memory on AArch64.
@@ -48,136 +49,186 @@
public final class AArch64ZeroMemoryOp extends AArch64LIRInstruction {
public static final LIRInstructionClass<AArch64ZeroMemoryOp> TYPE = LIRInstructionClass.create(AArch64ZeroMemoryOp.class);
- @Use({REG}) protected AllocatableValue addressValue;
- @Use({REG}) protected AllocatableValue lengthValue;
+ @Use({REG}) protected Value addressValue;
+ @Use({REG}) protected Value lengthValue;
+ @Temp({REG}) protected Value addressValueTemp;
+ @Temp({REG}) protected Value lengthValueTemp;
+
+ private final boolean isAligned;
private final boolean useDcZva;
private final int zvaLength;
/**
* Constructor of AArch64ZeroMemoryOp.
*
- * @param address allocatable 8-byte aligned base address of the memory chunk.
- * @param length allocatable length of the memory chunk, the value must be multiple of 8.
+ * @param address starting address of the memory chunk to be zeroed.
+ * @param length size of the memory chunk to be zeroed, in bytes.
+ * @param isAligned whether both address and size are aligned to 8 bytes.
* @param useDcZva is DC ZVA instruction is able to use.
* @param zvaLength the ZVA length info of current AArch64 CPU, negative value indicates length
* is unknown at compile time.
*/
- public AArch64ZeroMemoryOp(AllocatableValue address, AllocatableValue length, boolean useDcZva, int zvaLength) {
+ public AArch64ZeroMemoryOp(Value address, Value length, boolean isAligned, boolean useDcZva, int zvaLength) {
super(TYPE);
this.addressValue = address;
this.lengthValue = length;
+ this.addressValueTemp = address;
+ this.lengthValueTemp = length;
this.useDcZva = useDcZva;
this.zvaLength = zvaLength;
+ this.isAligned = isAligned;
}
@Override
protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
Register base = asRegister(addressValue);
Register size = asRegister(lengthValue);
- if (useDcZva && zvaLength > 0) {
- // From ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register:
- // A valid ZVA length should be a power-of-2 value in [4, 2048]
- assert (CodeUtil.isPowerOf2(zvaLength) && 4 <= zvaLength && zvaLength <= 2048);
- emitZeroMemoryWithDc(masm, base, size, zvaLength);
- } else {
- // Use store pair instructions (STP) to zero memory as a fallback.
- emitZeroMemoryWithStp(masm, base, size);
- }
- }
+
+ try (AArch64MacroAssembler.ScratchRegister scratchRegister = masm.getScratchRegister()) {
+ Register alignmentBits = scratchRegister.getRegister();
+
+ Label tail = new Label();
+ Label done = new Label();
+
+ // Jump to DONE if size is zero.
+ masm.cbz(64, size, done);
+
+ if (!isAligned) {
+ Label baseAlignedTo2Bytes = new Label();
+ Label baseAlignedTo4Bytes = new Label();
+ Label baseAlignedTo8Bytes = new Label();
+
+ // Jump to per-byte zeroing loop if the zeroing size is less than 8
+ masm.cmp(64, size, 8);
+ masm.branchConditionally(ConditionFlag.LT, tail);
+
+ // Make base 8-byte aligned
+ masm.neg(64, alignmentBits, base);
+ masm.and(64, alignmentBits, alignmentBits, 7);
+
+ masm.tbz(alignmentBits, 0, baseAlignedTo2Bytes);
+ masm.sub(64, size, size, 1);
+ masm.str(8, zr, AArch64Address.createPostIndexedImmediateAddress(base, 1));
+ masm.bind(baseAlignedTo2Bytes);
+
+ masm.tbz(alignmentBits, 1, baseAlignedTo4Bytes);
+ masm.sub(64, size, size, 2);
+ masm.str(16, zr, AArch64Address.createPostIndexedImmediateAddress(base, 2));
+ masm.bind(baseAlignedTo4Bytes);
- /**
- * Zero a chunk of memory with DC ZVA instructions.
- *
- * @param masm the AArch64 macro assembler.
- * @param base base an 8-byte aligned address of the memory chunk to be zeroed.
- * @param size size of the memory chunk to be zeroed, in bytes, must be multiple of 8.
- * @param zvaLength the ZVA length info of current AArch64 CPU.
- */
- private static void emitZeroMemoryWithDc(AArch64MacroAssembler masm, Register base, Register size, int zvaLength) {
- Label preLoop = new Label();
- Label zvaLoop = new Label();
- Label postLoop = new Label();
- Label tail = new Label();
- Label done = new Label();
+ masm.tbz(alignmentBits, 2, baseAlignedTo8Bytes);
+ masm.sub(64, size, size, 4);
+ masm.str(32, zr, AArch64Address.createPostIndexedImmediateAddress(base, 4));
+ masm.bind(baseAlignedTo8Bytes);
+ // At this point base is 8-byte aligned.
+ }
+
+ if (useDcZva && zvaLength > 0) {
+ // From ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register:
+ // A valid ZVA length should be a power-of-2 value in [4, 2048]
+ assert (CodeUtil.isPowerOf2(zvaLength) && 4 <= zvaLength && zvaLength <= 2048);
- try (AArch64MacroAssembler.ScratchRegister sc1 = masm.getScratchRegister()) {
- Register rscratch1 = sc1.getRegister();
+ Label preCheck = new Label();
+ Label preLoop = new Label();
+ Label mainCheck = new Label();
+ Label mainLoop = new Label();
+ Label postCheck = new Label();
+ Label postLoop = new Label();
+
+ masm.neg(64, alignmentBits, base);
+ masm.and(64, alignmentBits, alignmentBits, zvaLength - 1);
- // Count number of bytes to be pre-zeroed to align base address with ZVA length.
- masm.neg(64, rscratch1, base);
- masm.and(64, rscratch1, rscratch1, zvaLength - 1);
+ // Is size less than number of bytes to be pre-zeroed? Jump to post check if so.
+ masm.cmp(64, size, alignmentBits);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.LE, postCheck);
+ masm.sub(64, size, size, alignmentBits);
+
+ // Pre loop: align base according to the supported bulk zeroing stride.
+ masm.jmp(preCheck);
+
+ masm.align(crb.target.wordSize * 2);
+ masm.bind(preLoop);
+ masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+ masm.bind(preCheck);
+ masm.subs(64, alignmentBits, alignmentBits, 8);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, preLoop);
- // Is size less than number of bytes to be pre-zeroed? Jump to POST_LOOP if so.
- masm.cmp(64, size, rscratch1);
- masm.branchConditionally(AArch64Assembler.ConditionFlag.LE, postLoop);
- masm.sub(64, size, size, rscratch1);
+ // Main loop: bulk zeroing
+ masm.jmp(mainCheck);
+
+ masm.align(crb.target.wordSize * 2);
+ masm.bind(mainLoop);
+ masm.dc(AArch64Assembler.DataCacheOperationType.ZVA, base);
+ masm.add(64, base, base, zvaLength);
+ masm.bind(mainCheck);
+ masm.subs(64, size, size, zvaLength);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, mainLoop);
+
+ masm.add(64, size, size, zvaLength);
+
+ // Post loop: handle bytes after the main loop
+ masm.jmp(postCheck);
- // Pre-ZVA loop.
- masm.bind(preLoop);
- masm.subs(64, rscratch1, rscratch1, 8);
- masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, zvaLoop);
- masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
- masm.jmp(preLoop);
+ masm.align(crb.target.wordSize * 2);
+ masm.bind(postLoop);
+ masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+ masm.bind(postCheck);
+ masm.subs(64, size, size, 8);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, postLoop);
+
+ if (!isAligned) {
+ // Restore size for tail zeroing
+ masm.add(64, size, size, 8);
+ }
+ } else {
+ Label mainCheck = new Label();
+ Label mainLoop = new Label();
+
+ if (!isAligned) {
+ // After aligning base, we may have size less than 8. Need to check again.
+ masm.cmp(64, size, 8);
+ masm.branchConditionally(ConditionFlag.LT, tail);
+ }
- // ZVA loop.
- masm.bind(zvaLoop);
- masm.subs(64, size, size, zvaLength);
- masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, tail);
- masm.dc(AArch64Assembler.DataCacheOperationType.ZVA, base);
- masm.add(64, base, base, zvaLength);
- masm.jmp(zvaLoop);
+ masm.tbz(base, 3, mainCheck);
+ masm.sub(64, size, size, 8);
+ masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+ masm.jmp(mainCheck);
- // Handle bytes after ZVA loop.
+ // The STP loop that zeros 16 bytes in each iteration.
+ masm.align(crb.target.wordSize * 2);
+ masm.bind(mainLoop);
+ masm.stp(64, zr, zr, AArch64Address.createPostIndexedImmediateAddress(base, 2));
+ masm.bind(mainCheck);
+ masm.subs(64, size, size, 16);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, mainLoop);
+
+ // We may need to zero the tail 8 bytes of the memory chunk.
+ masm.add(64, size, size, 16);
+ masm.tbz(size, 3, tail);
+ masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+
+ if (!isAligned) {
+ // Adjust size for tail zeroing
+ masm.sub(64, size, size, 8);
+ }
+ }
+
masm.bind(tail);
- masm.add(64, size, size, zvaLength);
+ if (!isAligned) {
+ Label perByteZeroingLoop = new Label();
- // Post-ZVA loop.
- masm.bind(postLoop);
- masm.subs(64, size, size, 8);
- masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, done);
- masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
- masm.jmp(postLoop);
-
- // Done.
+ masm.cbz(64, size, done);
+ // We have to ensure size > 0 when entering the following loop
+ masm.align(crb.target.wordSize * 2);
+ masm.bind(perByteZeroingLoop);
+ masm.str(8, zr, AArch64Address.createPostIndexedImmediateAddress(base, 1));
+ masm.subs(64, size, size, 1);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.NE, perByteZeroingLoop);
+ }
masm.bind(done);
}
}
- /**
- * Zero a chunk of memory with STP instructions.
- *
- * @param masm the AArch64 macro assembler.
- * @param base base an 8-byte aligned address of the memory chunk to be zeroed.
- * @param size size of the memory chunk to be zeroed, in bytes, must be multiple of 8.
- */
- private static void emitZeroMemoryWithStp(AArch64MacroAssembler masm, Register base, Register size) {
- Label loop = new Label();
- Label tail = new Label();
- Label done = new Label();
-
- // Jump to DONE if size is zero.
- masm.cbz(64, size, done);
-
- // Is base address already 16-byte aligned? Jump to LDP loop if so.
- masm.tbz(base, 3, loop);
- masm.sub(64, size, size, 8);
- masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
-
- // The STP loop that zeros 16 bytes in each iteration.
- masm.bind(loop);
- masm.subs(64, size, size, 16);
- masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, tail);
- masm.stp(64, zr, zr, AArch64Address.createPostIndexedImmediateAddress(base, 2));
- masm.jmp(loop);
-
- // We may need to zero the tail 8 bytes of the memory chunk.
- masm.bind(tail);
- masm.adds(64, size, size, 16);
- masm.branchConditionally(AArch64Assembler.ConditionFlag.EQ, done);
- masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
-
- // Done.
- masm.bind(done);
- }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -115,7 +115,7 @@
public class SPARCControlFlow {
// This describes the maximum offset between the first emitted (load constant in to scratch,
// if does not fit into simm5 of cbcond) instruction and the final branch instruction
- private static final int maximumSelfOffsetInstructions = 2;
+ private static final int maximumSelfOffsetInstructions = 10;
public static final class ReturnOp extends SPARCBlockEndOp {
public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Wed Oct 16 11:23:46 2019 +0200
@@ -355,7 +355,7 @@
}
@SuppressWarnings("unused")
- default void emitZeroMemory(Value address, Value length) {
+ default void emitZeroMemory(Value address, Value length, boolean isAligned) {
throw GraalError.unimplemented("Bulk zeroing is not implemented on this architecture");
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -245,60 +245,40 @@
// Discard the segment entry and its flow, after if merging it into the loop
StructuredGraph graph = mainLoopBegin.graph();
IfNode loopTest = mainCounted.getLimitTest();
- IfNode newSegmentTest = getDuplicatedNode(loopTest);
- AbstractBeginNode trueSuccessor = loopTest.trueSuccessor();
- AbstractBeginNode falseSuccessor = loopTest.falseSuccessor();
- FixedNode firstNode;
- boolean codeInTrueSide = false;
- if (trueSuccessor == mainCounted.getBody()) {
- firstNode = trueSuccessor.next();
- codeInTrueSide = true;
- } else {
- assert (falseSuccessor == mainCounted.getBody());
- firstNode = falseSuccessor.next();
- }
- trueSuccessor = newSegmentTest.trueSuccessor();
- falseSuccessor = newSegmentTest.falseSuccessor();
+ IfNode newSegmentLoopTest = getDuplicatedNode(loopTest);
+
+ // Redirect anchors
+ AbstractBeginNode falseSuccessor = newSegmentLoopTest.falseSuccessor();
for (Node usage : falseSuccessor.anchored().snapshot()) {
usage.replaceFirstInput(falseSuccessor, loopTest.falseSuccessor());
}
+ AbstractBeginNode trueSuccessor = newSegmentLoopTest.trueSuccessor();
for (Node usage : trueSuccessor.anchored().snapshot()) {
usage.replaceFirstInput(trueSuccessor, loopTest.trueSuccessor());
}
- AbstractBeginNode startBlockNode;
- if (codeInTrueSide) {
- startBlockNode = trueSuccessor;
- } else {
- graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "before");
- startBlockNode = falseSuccessor;
- }
- FixedNode lastNode = getBlockEnd(startBlockNode);
- LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
- FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
- FixedNode newSegmentFirstNode = getDuplicatedNode(firstNode);
- FixedWithNextNode newSegmentLastNode = getDuplicatedNode(lastCodeNode);
- graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "Before placing segment");
- if (firstNode instanceof LoopEndNode) {
+
+ // remove if test
+ graph.removeSplitPropagate(newSegmentLoopTest, loopTest.trueSuccessor() == mainCounted.getBody() ? trueSuccessor : falseSuccessor);
+
+ graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "Before placing segment");
+ if (mainCounted.getBody().next() instanceof LoopEndNode) {
GraphUtil.killCFG(getDuplicatedNode(mainLoopBegin));
} else {
- newSegmentLastNode.clearSuccessors();
- startBlockNode.setNext(lastNode);
+ AbstractBeginNode newSegmentBegin = getDuplicatedNode(mainLoopBegin);
+ FixedNode newSegmentFirstNode = newSegmentBegin.next();
+ EndNode newSegmentEnd = getBlockEnd(newSegmentBegin);
+ FixedWithNextNode newSegmentLastNode = (FixedWithNextNode) newSegmentEnd.predecessor();
+ LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
+ FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
+
+ newSegmentBegin.clearSuccessors();
lastCodeNode.replaceFirstSuccessor(loopEndNode, newSegmentFirstNode);
- newSegmentLastNode.replaceFirstSuccessor(lastNode, loopEndNode);
- lastCodeNode.setNext(newSegmentFirstNode);
- newSegmentLastNode.setNext(loopEndNode);
- startBlockNode.clearSuccessors();
- lastNode.safeDelete();
- Node newSegmentTestStart = newSegmentTest.predecessor();
- LogicNode newSegmentIfTest = newSegmentTest.condition();
- newSegmentTestStart.clearSuccessors();
- newSegmentTest.safeDelete();
- newSegmentIfTest.safeDelete();
- trueSuccessor.safeDelete();
- falseSuccessor.safeDelete();
- newSegmentTestStart.safeDelete();
+ newSegmentLastNode.replaceFirstSuccessor(newSegmentEnd, loopEndNode);
+
+ newSegmentBegin.safeDelete();
+ newSegmentEnd.safeDelete();
}
- graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "After placing segment");
+ graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "After placing segment");
}
private static EndNode getBlockEnd(FixedNode node) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ExceptionLivenessTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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.graalvm.compiler.nodes.test;
+
+import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
+
+import org.graalvm.compiler.core.phases.HighTier;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.options.OptionValues;
+import org.junit.Test;
+
+public class ExceptionLivenessTest extends GraalCompilerTest {
+ @Test
+ public void testNewarray() {
+ OptionValues options = new OptionValues(getInitialOptions(), HighTier.Options.Inline, false, InlineDuringParsing, false);
+ test(options, "newarraySnippet");
+ }
+
+ public static int[] newarraySnippet() {
+ int[] array = new int[4];
+
+ dummy();
+ try {
+ array = new int[-10];
+ } catch (NegativeArraySizeException exc3) {
+ }
+ return array;
+ }
+
+ @BytecodeParserNeverInline
+ static void dummy() {
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -32,6 +32,7 @@
import org.graalvm.compiler.graph.IterableNodeType;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -97,6 +98,19 @@
}
}
+ public boolean isUsedAsGuardInput() {
+ if (this.hasUsages()) {
+ for (Node n : usages()) {
+ for (Position inputPosition : n.inputPositions()) {
+ if (inputPosition.getInputType() == InputType.Guard && inputPosition.get(n) == this) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
public NodeIterable<GuardNode> guards() {
return usages().filter(GuardNode.class);
}
@@ -105,6 +119,10 @@
return usages();
}
+ public boolean hasAnchored() {
+ return this.hasUsages();
+ }
+
public NodeIterable<FixedNode> getBlockNodes() {
return new NodeIterable<FixedNode>() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -548,7 +548,7 @@
return false;
}
- if (trueSuccessor().anchored().isNotEmpty() || falseSuccessor().anchored().isNotEmpty()) {
+ if (trueSuccessor().hasAnchored() || falseSuccessor().hasAnchored()) {
return false;
}
@@ -1216,6 +1216,10 @@
return false;
}
+ if (trueSuccessor().isUsedAsGuardInput() || falseSuccessor().isUsedAsGuardInput()) {
+ return false;
+ }
+
ValuePhiNode phi = (ValuePhiNode) generalPhi;
EconomicMap<Node, NodeColor> coloredNodes = EconomicMap.create(Equivalence.IDENTITY, 8);
@@ -1645,6 +1649,10 @@
return false;
}
+ if (trueSuccessor().isUsedAsGuardInput() || falseSuccessor().isUsedAsGuardInput()) {
+ return false;
+ }
+
// Ensure phi is used by at most the comparison and the merge's frame state (if any)
ValuePhiNode phi = (ValuePhiNode) singleUsage;
NodeIterable<Node> phiUsages = phi.usages();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -26,8 +26,10 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Abs;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
@@ -46,7 +48,7 @@
public static final NodeClass<AbsNode> TYPE = NodeClass.create(AbsNode.class);
public AbsNode(ValueNode x) {
- super(TYPE, ArithmeticOpTable::getAbs, x);
+ super(TYPE, getArithmeticOpTable(x).getAbs(), x);
}
public static ValueNode create(ValueNode value, NodeView view) {
@@ -67,6 +69,11 @@
}
@Override
+ protected UnaryOp<Abs> getOp(ArithmeticOpTable table) {
+ return table.getAbs();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
ValueNode ret = super.canonical(tool, forValue);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -54,7 +54,7 @@
}
protected AddNode(NodeClass<? extends AddNode> c, ValueNode x, ValueNode y) {
- super(c, ArithmeticOpTable::getAdd, x, y);
+ super(c, getArithmeticOpTable(x).getAdd(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -71,6 +71,11 @@
}
}
+ @Override
+ protected BinaryOp<Add> getOp(ArithmeticOpTable table) {
+ return table.getAdd();
+ }
+
private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY, NodeView view) {
AddNode self = addNode;
boolean associative = op.isAssociative();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -51,7 +51,7 @@
public static final NodeClass<AndNode> TYPE = NodeClass.create(AndNode.class);
public AndNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getAnd, x, y);
+ super(TYPE, getArithmeticOpTable(x).getAnd(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -65,6 +65,11 @@
}
@Override
+ protected BinaryOp<And> getOp(ArithmeticOpTable table) {
+ return table.getAnd();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
ValueNode ret = super.canonical(tool, forX, forY);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -27,9 +27,6 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
-import java.io.Serializable;
-import java.util.function.Function;
-
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.IntegerStamp;
@@ -58,20 +55,20 @@
@SuppressWarnings("rawtypes") public static final NodeClass<BinaryArithmeticNode> TYPE = NodeClass.create(BinaryArithmeticNode.class);
- protected interface SerializableBinaryFunction<T> extends Function<ArithmeticOpTable, BinaryOp<T>>, Serializable {
+ protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, BinaryOp<OP> opForStampComputation, ValueNode x, ValueNode y) {
+ super(c, opForStampComputation.foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
}
- protected final SerializableBinaryFunction<OP> getOp;
-
- protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, SerializableBinaryFunction<OP> getOp, ValueNode x, ValueNode y) {
- super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
- this.getOp = getOp;
+ public static ArithmeticOpTable getArithmeticOpTable(ValueNode forValue) {
+ return ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT));
}
+ protected abstract BinaryOp<OP> getOp(ArithmeticOpTable table);
+
protected final BinaryOp<OP> getOp(ValueNode forX, ValueNode forY) {
- ArithmeticOpTable table = ArithmeticOpTable.forStamp(forX.stamp(NodeView.DEFAULT));
- assert table.equals(ArithmeticOpTable.forStamp(forY.stamp(NodeView.DEFAULT)));
- return getOp.apply(table);
+ ArithmeticOpTable table = getArithmeticOpTable(forX);
+ assert table.equals(getArithmeticOpTable(forY));
+ return getOp(table);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -25,12 +25,12 @@
package org.graalvm.compiler.nodes.calc;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
-
-import java.util.EnumMap;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.calc.FloatConvert;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.FloatConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
@@ -55,16 +55,8 @@
protected final FloatConvert op;
- private static final EnumMap<FloatConvert, SerializableUnaryFunction<FloatConvertOp>> getOps;
- static {
- getOps = new EnumMap<>(FloatConvert.class);
- for (FloatConvert op : FloatConvert.values()) {
- getOps.put(op, table -> table.getFloatConvert(op));
- }
- }
-
public FloatConvertNode(FloatConvert op, ValueNode input) {
- super(TYPE, getOps.get(op), input);
+ super(TYPE, getArithmeticOpTable(input).getFloatConvert(op), input);
this.op = op;
}
@@ -76,6 +68,11 @@
return new FloatConvertNode(op, input);
}
+ @Override
+ protected UnaryOp<FloatConvertOp> getOp(ArithmeticOpTable table) {
+ return table.getFloatConvert(op);
+ }
+
public FloatConvert getFloatConvert() {
return op;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -52,7 +52,7 @@
}
protected FloatDivNode(NodeClass<? extends FloatDivNode> c, ValueNode x, ValueNode y) {
- super(c, ArithmeticOpTable::getDiv, x, y);
+ super(c, getArithmeticOpTable(x).getDiv(), x, y);
assert stamp instanceof FloatStamp;
}
@@ -67,6 +67,11 @@
}
@Override
+ protected BinaryOp<Div> getOp(ArithmeticOpTable table) {
+ return table.getDiv();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
ValueNode ret = super.canonical(tool, forX, forY);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -24,8 +24,7 @@
package org.graalvm.compiler.nodes.calc;
-import java.io.Serializable;
-import java.util.function.Function;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
@@ -53,20 +52,11 @@
public abstract class IntegerConvertNode<OP, REV> extends UnaryNode implements ArithmeticOperation, ConvertNode, ArithmeticLIRLowerable, StampInverter {
@SuppressWarnings("rawtypes") public static final NodeClass<IntegerConvertNode> TYPE = NodeClass.create(IntegerConvertNode.class);
- protected final SerializableIntegerConvertFunction<OP> getOp;
- protected final SerializableIntegerConvertFunction<REV> getReverseOp;
-
protected final int inputBits;
protected final int resultBits;
- protected interface SerializableIntegerConvertFunction<T> extends Function<ArithmeticOpTable, IntegerConvertOp<T>>, Serializable {
- }
-
- protected IntegerConvertNode(NodeClass<? extends IntegerConvertNode<OP, REV>> c, SerializableIntegerConvertFunction<OP> getOp, SerializableIntegerConvertFunction<REV> getReverseOp, int inputBits,
- int resultBits, ValueNode input) {
- super(c, getOp.apply(ArithmeticOpTable.forStamp(input.stamp(NodeView.DEFAULT))).foldStamp(inputBits, resultBits, input.stamp(NodeView.DEFAULT)), input);
- this.getOp = getOp;
- this.getReverseOp = getReverseOp;
+ protected IntegerConvertNode(NodeClass<? extends IntegerConvertNode<OP, REV>> c, IntegerConvertOp<OP> opForStampComputation, int inputBits, int resultBits, ValueNode input) {
+ super(c, opForStampComputation.foldStamp(inputBits, resultBits, input.stamp(NodeView.DEFAULT)), input);
this.inputBits = inputBits;
this.resultBits = resultBits;
assert PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) == 0 || PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) == inputBits;
@@ -80,13 +70,13 @@
return resultBits;
}
- protected final IntegerConvertOp<OP> getOp(ValueNode forValue) {
- return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
- }
+ protected abstract IntegerConvertOp<OP> getOp(ArithmeticOpTable table);
+
+ protected abstract IntegerConvertOp<REV> getReverseOp(ArithmeticOpTable table);
@Override
public final IntegerConvertOp<OP> getArithmeticOp() {
- return getOp(getValue());
+ return getOp(getArithmeticOpTable(getValue()));
}
@Override
@@ -96,7 +86,7 @@
@Override
public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) {
- IntegerConvertOp<REV> reverse = getReverseOp.apply(ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)));
+ IntegerConvertOp<REV> reverse = getReverseOp(ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)));
return reverse.foldConstant(getResultBits(), getInputBits(), c);
}
@@ -108,7 +98,7 @@
@Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
- ValueNode synonym = findSynonym(getOp(forValue), forValue, inputBits, resultBits, stamp(NodeView.DEFAULT));
+ ValueNode synonym = findSynonym(getOp(getArithmeticOpTable(forValue)), forValue, inputBits, resultBits, stamp(NodeView.DEFAULT));
if (synonym != null) {
return synonym;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerMulHighNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerMulHighNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -28,6 +28,7 @@
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.MulHigh;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable;
@@ -48,7 +49,12 @@
public static final NodeClass<IntegerMulHighNode> TYPE = NodeClass.create(IntegerMulHighNode.class);
public IntegerMulHighNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getMulHigh, x, y);
+ super(TYPE, getArithmeticOpTable(x).getMulHigh(), x, y);
+ }
+
+ @Override
+ protected BinaryOp<MulHigh> getOp(ArithmeticOpTable table) {
+ return table.getMulHigh();
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -24,7 +24,10 @@
package org.graalvm.compiler.nodes.calc;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
+
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.Shl;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -45,7 +48,7 @@
public static final NodeClass<LeftShiftNode> TYPE = NodeClass.create(LeftShiftNode.class);
public LeftShiftNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getShl, x, y);
+ super(TYPE, getArithmeticOpTable(x).getShl(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -60,6 +63,11 @@
}
@Override
+ protected ShiftOp<Shl> getOp(ArithmeticOpTable table) {
+ return table.getShl();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
ValueNode ret = super.canonical(tool, forX, forY);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -27,9 +27,9 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
-import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Mul;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
@@ -56,7 +56,7 @@
}
protected MulNode(NodeClass<? extends MulNode> c, ValueNode x, ValueNode y) {
- super(c, ArithmeticOpTable::getMul, x, y);
+ super(c, getArithmeticOpTable(x).getMul(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -70,6 +70,11 @@
}
@Override
+ protected BinaryOp<Mul> getOp(ArithmeticOpTable table) {
+ return table.getMul();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
ValueNode ret = super.canonical(tool, forX, forY);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -25,6 +25,7 @@
package org.graalvm.compiler.nodes.calc;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
@@ -58,7 +59,7 @@
}
public NarrowNode(ValueNode input, int inputBits, int resultBits) {
- super(TYPE, ArithmeticOpTable::getNarrow, ArithmeticOpTable::getSignExtend, inputBits, resultBits, input);
+ super(TYPE, getArithmeticOpTable(input).getNarrow(), inputBits, resultBits, input);
}
public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
@@ -76,6 +77,16 @@
}
@Override
+ protected IntegerConvertOp<Narrow> getOp(ArithmeticOpTable table) {
+ return table.getNarrow();
+ }
+
+ @Override
+ protected IntegerConvertOp<SignExtend> getReverseOp(ArithmeticOpTable table) {
+ return table.getSignExtend();
+ }
+
+ @Override
public boolean isLossless() {
return checkLossless(this.getResultBits());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -26,8 +26,10 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Neg;
import org.graalvm.compiler.core.common.type.FloatStamp;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -49,7 +51,7 @@
public static final NodeClass<NegateNode> TYPE = NodeClass.create(NegateNode.class);
public NegateNode(ValueNode value) {
- super(TYPE, ArithmeticOpTable::getNeg, value);
+ super(TYPE, getArithmeticOpTable(value).getNeg(), value);
}
public static ValueNode create(ValueNode value, NodeView view) {
@@ -61,6 +63,11 @@
}
@Override
+ protected UnaryOp<Neg> getOp(ArithmeticOpTable table) {
+ return table.getNeg();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
ValueNode synonym = findSynonym(forValue, getOp(forValue));
if (synonym != null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -26,8 +26,10 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Not;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.NodeClass;
@@ -48,7 +50,7 @@
public static final NodeClass<NotNode> TYPE = NodeClass.create(NotNode.class);
protected NotNode(ValueNode x) {
- super(TYPE, ArithmeticOpTable::getNot, x);
+ super(TYPE, getArithmeticOpTable(x).getNot(), x);
}
public static ValueNode create(ValueNode x) {
@@ -56,6 +58,11 @@
}
@Override
+ protected UnaryOp<Not> getOp(ArithmeticOpTable table) {
+ return table.getNot();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
ValueNode ret = super.canonical(tool, forValue);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -39,10 +39,13 @@
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.extended.BoxNode;
import org.graalvm.compiler.nodes.extended.GetClassNode;
+import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.spi.Virtualizable;
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
import org.graalvm.compiler.nodes.virtual.VirtualBoxingNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.OptionValues;
@@ -112,6 +115,11 @@
}
return LogicConstantNode.forBoolean(false);
}
+ if (nonConstant instanceof AbstractNewObjectNode || nonConstant instanceof AllocatedObjectNode) {
+ assert !(nonConstant instanceof BoxNode); // guard against class hierarchy changes
+ // a constant can never be equals to a new object
+ return LogicConstantNode.forBoolean(false);
+ }
return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue, view);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -50,7 +50,7 @@
public static final NodeClass<OrNode> TYPE = NodeClass.create(OrNode.class);
public OrNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getOr, x, y);
+ super(TYPE, getArithmeticOpTable(x).getOr(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -64,6 +64,11 @@
}
@Override
+ protected BinaryOp<Or> getOp(ArithmeticOpTable table) {
+ return table.getOr();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
NodeView view = NodeView.from(tool);
ValueNode ret = super.canonical(tool, forX, forY);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -50,7 +50,7 @@
}
protected RemNode(NodeClass<? extends RemNode> c, ValueNode x, ValueNode y) {
- super(c, ArithmeticOpTable::getRem, x, y);
+ super(c, getArithmeticOpTable(x).getRem(), x, y);
}
public static ValueNode create(ValueNode forX, ValueNode forY, NodeView view) {
@@ -64,6 +64,11 @@
}
@Override
+ protected BinaryOp<Rem> getOp(ArithmeticOpTable table) {
+ return table.getRem();
+ }
+
+ @Override
public void lower(LoweringTool tool) {
tool.getLowerer().lower(this, tool);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -24,7 +24,10 @@
package org.graalvm.compiler.nodes.calc;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
+
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.Shr;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -45,7 +48,7 @@
public static final NodeClass<RightShiftNode> TYPE = NodeClass.create(RightShiftNode.class);
public RightShiftNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getShr, x, y);
+ super(TYPE, getArithmeticOpTable(x).getShr(), x, y);
}
public static ValueNode create(ValueNode x, int y, NodeView view) {
@@ -67,6 +70,11 @@
}
@Override
+ protected ShiftOp<Shr> getOp(ArithmeticOpTable table) {
+ return table.getShr();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
NodeView view = NodeView.from(tool);
ValueNode ret = super.canonical(tool, forX, forY);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -26,9 +26,7 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
-
-import java.io.Serializable;
-import java.util.function.Function;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
@@ -55,25 +53,21 @@
@SuppressWarnings("rawtypes") public static final NodeClass<ShiftNode> TYPE = NodeClass.create(ShiftNode.class);
- protected interface SerializableShiftFunction<T> extends Function<ArithmeticOpTable, ShiftOp<T>>, Serializable {
- }
-
- protected final SerializableShiftFunction<OP> getOp;
-
/**
* Creates a new shift operation.
*
* @param x the first input value
* @param s the second input value
*/
- protected ShiftNode(NodeClass<? extends ShiftNode<OP>> c, SerializableShiftFunction<OP> getOp, ValueNode x, ValueNode s) {
- super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), (IntegerStamp) s.stamp(NodeView.DEFAULT)), x, s);
+ protected ShiftNode(NodeClass<? extends ShiftNode<OP>> c, ShiftOp<OP> opForStampComputation, ValueNode x, ValueNode s) {
+ super(c, opForStampComputation.foldStamp(x.stamp(NodeView.DEFAULT), (IntegerStamp) s.stamp(NodeView.DEFAULT)), x, s);
assert ((IntegerStamp) s.stamp(NodeView.DEFAULT)).getBits() == 32;
- this.getOp = getOp;
}
+ protected abstract ShiftOp<OP> getOp(ArithmeticOpTable table);
+
protected final ShiftOp<OP> getOp(ValueNode forValue) {
- return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
+ return getOp(getArithmeticOpTable(forValue));
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -25,8 +25,8 @@
package org.graalvm.compiler.nodes.calc;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
-import jdk.vm.ci.code.CodeUtil;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow;
@@ -42,6 +42,8 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import jdk.vm.ci.code.CodeUtil;
+
/**
* The {@code SignExtendNode} converts an integer to a wider integer using sign extension.
*/
@@ -56,7 +58,7 @@
}
public SignExtendNode(ValueNode input, int inputBits, int resultBits) {
- super(TYPE, ArithmeticOpTable::getSignExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
+ super(TYPE, getArithmeticOpTable(input).getSignExtend(), inputBits, resultBits, input);
}
public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
@@ -73,6 +75,16 @@
}
@Override
+ protected IntegerConvertOp<SignExtend> getOp(ArithmeticOpTable table) {
+ return table.getSignExtend();
+ }
+
+ @Override
+ protected IntegerConvertOp<Narrow> getReverseOp(ArithmeticOpTable table) {
+ return table.getNarrow();
+ }
+
+ @Override
public boolean isLossless() {
return true;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -26,8 +26,10 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_16;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
@@ -47,7 +49,7 @@
public static final NodeClass<SqrtNode> TYPE = NodeClass.create(SqrtNode.class);
protected SqrtNode(ValueNode x) {
- super(TYPE, ArithmeticOpTable::getSqrt, x);
+ super(TYPE, getArithmeticOpTable(x).getSqrt(), x);
}
public static ValueNode create(ValueNode x, NodeView view) {
@@ -59,6 +61,11 @@
}
@Override
+ protected UnaryOp<Sqrt> getOp(ArithmeticOpTable table) {
+ return table.getSqrt();
+ }
+
+ @Override
public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
nodeValueMap.setResult(this, gen.emitMathSqrt(nodeValueMap.operand(getValue())));
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -53,7 +53,7 @@
}
protected SubNode(NodeClass<? extends SubNode> c, ValueNode x, ValueNode y) {
- super(c, ArithmeticOpTable::getSub, x, y);
+ super(c, getArithmeticOpTable(x).getSub(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -66,6 +66,11 @@
return canonical(null, op, stamp, x, y, view);
}
+ @Override
+ protected BinaryOp<Sub> getOp(ArithmeticOpTable table) {
+ return table.getSub();
+ }
+
private static ValueNode canonical(SubNode subNode, BinaryOp<Sub> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
SubNode self = subNode;
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -24,8 +24,7 @@
package org.graalvm.compiler.nodes.calc;
-import java.io.Serializable;
-import java.util.function.Function;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
@@ -44,18 +43,14 @@
@SuppressWarnings("rawtypes") public static final NodeClass<UnaryArithmeticNode> TYPE = NodeClass.create(UnaryArithmeticNode.class);
- protected interface SerializableUnaryFunction<T> extends Function<ArithmeticOpTable, UnaryOp<T>>, Serializable {
+ protected UnaryArithmeticNode(NodeClass<? extends UnaryArithmeticNode<OP>> c, UnaryOp<OP> opForStampComputation, ValueNode value) {
+ super(c, opForStampComputation.foldStamp(value.stamp(NodeView.DEFAULT)), value);
}
- protected final SerializableUnaryFunction<OP> getOp;
-
- protected UnaryArithmeticNode(NodeClass<? extends UnaryArithmeticNode<OP>> c, SerializableUnaryFunction<OP> getOp, ValueNode value) {
- super(c, getOp.apply(ArithmeticOpTable.forStamp(value.stamp(NodeView.DEFAULT))).foldStamp(value.stamp(NodeView.DEFAULT)), value);
- this.getOp = getOp;
- }
+ protected abstract UnaryOp<OP> getOp(ArithmeticOpTable table);
protected final UnaryOp<OP> getOp(ValueNode forValue) {
- return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
+ return getOp(getArithmeticOpTable(forValue));
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -24,8 +24,10 @@
package org.graalvm.compiler.nodes.calc;
-import jdk.vm.ci.code.CodeUtil;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
+
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.UShr;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -38,6 +40,7 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.meta.JavaKind;
@NodeInfo(shortName = ">>>")
@@ -46,7 +49,7 @@
public static final NodeClass<UnsignedRightShiftNode> TYPE = NodeClass.create(UnsignedRightShiftNode.class);
public UnsignedRightShiftNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getUShr, x, y);
+ super(TYPE, getArithmeticOpTable(x).getUShr(), x, y);
}
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -61,6 +64,11 @@
}
@Override
+ protected ShiftOp<UShr> getOp(ArithmeticOpTable table) {
+ return table.getUShr();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
NodeView view = NodeView.from(tool);
ValueNode ret = super.canonical(tool, forX, forY);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -50,7 +50,7 @@
public static final NodeClass<XorNode> TYPE = NodeClass.create(XorNode.class);
public XorNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getXor, x, y);
+ super(TYPE, getArithmeticOpTable(x).getXor(), x, y);
assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
}
@@ -65,6 +65,11 @@
}
@Override
+ protected BinaryOp<Xor> getOp(ArithmeticOpTable table) {
+ return table.getXor();
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
ValueNode ret = super.canonical(tool, forX, forY);
if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -25,6 +25,7 @@
package org.graalvm.compiler.nodes.calc;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
@@ -60,7 +61,7 @@
}
public ZeroExtendNode(ValueNode input, int inputBits, int resultBits, boolean inputAlwaysPositive) {
- super(TYPE, ArithmeticOpTable::getZeroExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
+ super(TYPE, getArithmeticOpTable(input).getZeroExtend(), inputBits, resultBits, input);
this.inputAlwaysPositive = inputAlwaysPositive;
}
@@ -82,6 +83,16 @@
}
@Override
+ protected IntegerConvertOp<ZeroExtend> getOp(ArithmeticOpTable table) {
+ return table.getZeroExtend();
+ }
+
+ @Override
+ protected IntegerConvertOp<Narrow> getReverseOp(ArithmeticOpTable table) {
+ return table.getNarrow();
+ }
+
+ @Override
public boolean isLossless() {
return true;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -429,11 +429,14 @@
}
/*
- * Collect dead successors. Successors have to be cleaned before adding the new node to the
- * graph.
+ * Surviving successors have to be cleaned before adding the new node to the graph. Keep the
+ * dead ones attached to the old node for later cleanup.
*/
- List<AbstractBeginNode> deadSuccessors = successors.filter(s -> !newSuccessors.contains(s)).snapshot();
- successors.clear();
+ for (int i = 0; i < successors.size(); i++) {
+ if (newSuccessors.contains(successors.get(i))) {
+ successors.set(i, null);
+ }
+ }
/*
* Create the new switch node. This is done before removing dead successors as `killCFG`
@@ -443,14 +446,11 @@
AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
SwitchNode newSwitch = graph().add(new IntegerSwitchNode(newValue, successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
- /* Remove dead successors. */
- for (AbstractBeginNode successor : deadSuccessors) {
- GraphUtil.killCFG(successor);
- }
-
/* Replace ourselves with the new switch */
((FixedWithNextNode) predecessor()).setNext(newSwitch);
- GraphUtil.killWithUnusedFloatingInputs(this);
+
+ // Remove the old switch and the dead successors.
+ GraphUtil.killCFG(this);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Wed Oct 16 11:23:46 2019 +0200
@@ -53,8 +53,7 @@
Integer smallestCompareWidth();
/**
- * Returns the granularity in terms of bytes that this target platform's bulk zeroing supports.
- * Returns 0 to indicate that this target platform does not support bulk zeroing instruction.
+ * Indicates whether this target platform supports bulk zeroing of arbitrary size.
*/
- int bulkZeroingStride();
+ boolean supportsBulkZeroing();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Wed Oct 16 11:23:46 2019 +0200
@@ -742,19 +742,22 @@
/**
* Tries to find an original value of the given node by traversing through proxies and
- * unambiguous phis. Note that this method will perform an exhaustive search through phis. It is
- * intended to be used during graph building, when phi nodes aren't yet canonicalized.
+ * unambiguous phis. Note that this method will perform an exhaustive search through phis.
*
- * @param value The node whose original value should be determined.
- * @return The original value (which might be the input value itself).
+ * @param value the node whose original value should be determined
+ * @param abortOnLoopPhi specifies if the traversal through phis should stop and return
+ * {@code value} if it hits a {@linkplain PhiNode#isLoopPhi loop phi}. This argument
+ * must be {@code true} if used during graph building as loop phi nodes may not yet
+ * have all their inputs computed.
+ * @return the original value (which might be {@code value} itself)
*/
- public static ValueNode originalValue(ValueNode value) {
- ValueNode result = originalValueSimple(value);
+ public static ValueNode originalValue(ValueNode value, boolean abortOnLoopPhi) {
+ ValueNode result = originalValueSimple(value, abortOnLoopPhi);
assert result != null;
return result;
}
- private static ValueNode originalValueSimple(ValueNode value) {
+ private static ValueNode originalValueSimple(ValueNode value, boolean abortOnLoopPhi) {
/* The very simple case: look through proxies. */
ValueNode cur = originalValueForProxy(value);
@@ -765,6 +768,10 @@
*/
PhiNode phi = (PhiNode) cur;
+ if (abortOnLoopPhi && phi.isLoopPhi()) {
+ return value;
+ }
+
ValueNode phiSingleValue = null;
int count = phi.valueCount();
for (int i = 0; i < count; ++i) {
@@ -783,7 +790,7 @@
* of the inputs is another phi function. We need to do a complicated
* exhaustive check.
*/
- return originalValueForComplicatedPhi(phi, new NodeBitMap(value.graph()));
+ return originalValueForComplicatedPhi(value, phi, new NodeBitMap(value.graph()), abortOnLoopPhi);
} else {
/*
* We have two different input values for the phi function, but none of them
@@ -819,8 +826,12 @@
/**
* Handling for complicated nestings of phi functions. We need to reduce phi functions
* recursively, and need a temporary map of visited nodes to avoid endless recursion of cycles.
+ *
+ * @param value the node whose original value is being determined
+ * @param abortOnLoopPhi specifies if the traversal through phis should stop and return
+ * {@code value} if it hits a {@linkplain PhiNode#isLoopPhi loop phi}
*/
- private static ValueNode originalValueForComplicatedPhi(PhiNode phi, NodeBitMap visited) {
+ private static ValueNode originalValueForComplicatedPhi(ValueNode value, PhiNode phi, NodeBitMap visited, boolean abortOnLoopPhi) {
if (visited.isMarked(phi)) {
/*
* Found a phi function that was already seen. Either a cycle, or just a second phi
@@ -836,7 +847,16 @@
ValueNode phiCurValue = originalValueForProxy(phi.valueAt(i));
if (phiCurValue instanceof PhiNode) {
/* Recursively process a phi function input. */
- phiCurValue = originalValueForComplicatedPhi((PhiNode) phiCurValue, visited);
+ PhiNode curPhi = (PhiNode) phiCurValue;
+ if (abortOnLoopPhi && curPhi.isLoopPhi()) {
+ return value;
+ }
+ phiCurValue = originalValueForComplicatedPhi(value, curPhi, visited, abortOnLoopPhi);
+ if (phiCurValue == value) {
+ // Hit a loop phi
+ assert abortOnLoopPhi;
+ return value;
+ }
}
if (phiCurValue == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Wed Oct 16 11:23:46 2019 +0200
@@ -47,6 +47,7 @@
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins;
import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
+import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode;
import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
@@ -61,16 +62,11 @@
@Override
public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins,
boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
- register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions);
+ register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions, useFMAIntrinsics);
}
public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
- boolean registerMathPlugins) {
- register(plugins, bytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, true);
- }
-
- public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
- boolean registerMathPlugins, boolean emitJDK9StringSubstitutions) {
+ boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
@@ -78,7 +74,7 @@
registerIntegerLongPlugins(invocationPlugins, JavaKind.Int, bytecodeProvider);
registerIntegerLongPlugins(invocationPlugins, JavaKind.Long, bytecodeProvider);
if (registerMathPlugins) {
- registerMathPlugins(invocationPlugins);
+ registerMathPlugins(invocationPlugins, useFMAIntrinsics);
}
if (emitJDK9StringSubstitutions) {
registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
@@ -130,7 +126,7 @@
});
}
- private static void registerMathPlugins(InvocationPlugins plugins) {
+ private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics) {
Registration r = new Registration(plugins, Math.class);
registerUnaryMath(r, "sin", SIN);
registerUnaryMath(r, "cos", COS);
@@ -148,6 +144,36 @@
registerRound(r, "rint", RoundingMode.NEAREST);
registerRound(r, "ceil", RoundingMode.UP);
registerRound(r, "floor", RoundingMode.DOWN);
+ if (useFMAIntrinsics && JavaVersionUtil.JAVA_SPEC > 8) {
+ registerFMA(r);
+ }
+ }
+
+ private static void registerFMA(Registration r) {
+ r.register3("fma", Double.TYPE, Double.TYPE, Double.TYPE, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b,
+ ResolvedJavaMethod targetMethod,
+ Receiver receiver,
+ ValueNode na,
+ ValueNode nb,
+ ValueNode nc) {
+ b.push(JavaKind.Double, b.append(new FusedMultiplyAddNode(na, nb, nc)));
+ return true;
+ }
+ });
+ r.register3("fma", Float.TYPE, Float.TYPE, Float.TYPE, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b,
+ ResolvedJavaMethod targetMethod,
+ Receiver receiver,
+ ValueNode na,
+ ValueNode nb,
+ ValueNode nc) {
+ b.push(JavaKind.Float, b.append(new FusedMultiplyAddNode(na, nb, nc)));
+ return true;
+ }
+ });
}
private static void registerUnaryMath(Registration r, String name, UnaryOperation operation) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -26,10 +26,12 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
-import jdk.vm.ci.meta.JavaConstant;
import org.graalvm.compiler.core.common.calc.FloatConvert;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.FloatConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -43,6 +45,8 @@
import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import jdk.vm.ci.meta.JavaConstant;
+
/**
* This node has the semantics of the AMD64 floating point conversions. It is used in the lowering
* of the {@link FloatConvertNode} which, on AMD64 needs a {@link AMD64FloatConvertNode} plus some
@@ -58,12 +62,17 @@
protected final FloatConvert op;
public AMD64FloatConvertNode(FloatConvert op, ValueNode value) {
- super(TYPE, table -> table.getFloatConvert(op), value);
+ super(TYPE, getArithmeticOpTable(value).getFloatConvert(op), value);
this.op = op;
this.stamp = this.stamp.meet(createInexactCaseStamp());
}
@Override
+ protected UnaryOp<FloatConvertOp> getOp(ArithmeticOpTable table) {
+ return table.getFloatConvert(op);
+ }
+
+ @Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
// nothing to do
return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -87,13 +87,6 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
-import org.graalvm.compiler.test.ModuleSupport;
-import org.graalvm.compiler.test.SubprocessUtil;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.bytecode.Bytecode;
@@ -111,6 +104,12 @@
import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
+import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.JavaField;
@@ -209,6 +208,17 @@
}
try {
checkClass(metaAccess, getSnippetReflection(), className);
+ } catch (UnsupportedClassVersionError e) {
+ // graal-test.jar can contain classes compiled for different
+ // Java versions
+ } catch (NoClassDefFoundError e) {
+ if (!e.getMessage().contains("Could not initialize class")) {
+ throw e;
+ } else {
+ // A second or later attempt to initialize a class
+ // results in this confusing error where the
+ // original cause of initialization failure is lost
+ }
} catch (ClassNotFoundException e) {
throw new AssertionError(e);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Wed Oct 16 11:23:46 2019 +0200
@@ -835,7 +835,7 @@
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode object = receiver.get();
- ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object));
+ ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object, true));
if (folded != null) {
b.addPush(JavaKind.Object, folded);
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -48,19 +48,21 @@
public static final NodeClass<ZeroMemoryNode> TYPE = NodeClass.create(ZeroMemoryNode.class);
@Input ValueNode length;
+ private final boolean isAligned;
- public ZeroMemoryNode(ValueNode address, ValueNode length, LocationIdentity locationIdentity) {
- this(OffsetAddressNode.create(address), length, locationIdentity, BarrierType.NONE);
+ public ZeroMemoryNode(ValueNode address, ValueNode length, boolean isAligned, LocationIdentity locationIdentity) {
+ this(OffsetAddressNode.create(address), length, isAligned, locationIdentity, BarrierType.NONE);
}
- public ZeroMemoryNode(AddressNode address, ValueNode length, LocationIdentity locationIdentity, BarrierType type) {
+ public ZeroMemoryNode(AddressNode address, ValueNode length, boolean isAligned, LocationIdentity locationIdentity, BarrierType type) {
super(TYPE, address, locationIdentity, StampFactory.forVoid(), type);
this.length = length;
+ this.isAligned = isAligned;
}
@Override
public void generate(NodeLIRBuilderTool gen) {
- gen.getLIRGeneratorTool().emitZeroMemory(gen.operand(getAddress()), gen.operand(length));
+ gen.getLIRGeneratorTool().emitZeroMemory(gen.operand(getAddress()), gen.operand(length), isAligned);
}
@Override
@@ -69,5 +71,5 @@
}
@NodeIntrinsic
- public static native void zero(Word address, long length, @ConstantNodeParameter LocationIdentity locationIdentity);
+ public static native void zero(Word address, long length, @ConstantNodeParameter boolean isAligned, @ConstantNodeParameter LocationIdentity locationIdentity);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -28,6 +28,7 @@
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.UMulHigh;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable;
@@ -49,7 +50,12 @@
public static final NodeClass<UnsignedMulHighNode> TYPE = NodeClass.create(UnsignedMulHighNode.class);
public UnsignedMulHighNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getUMulHigh, x, y);
+ super(TYPE, getArithmeticOpTable(x).getUMulHigh(), x, y);
+ }
+
+ @Override
+ protected BinaryOp<UMulHigh> getOp(ArithmeticOpTable table) {
+ return table.getUMulHigh();
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/DefaultGraphTypes.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/DefaultGraphTypes.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,10 +30,17 @@
private DefaultGraphTypes() {
}
+ @SuppressWarnings("unchecked")
@Override
public Class<?> enumClass(Object enumValue) {
if (enumValue instanceof Enum<?>) {
- return enumValue.getClass();
+ // check that the enum class is not actually an anonymous subclass:
+ Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) enumValue.getClass();
+ Enum<?>[] constants = enumClass.getEnumConstants();
+ if (constants == null && enumClass.isAnonymousClass()) {
+ enumClass = (Class<? extends Enum<?>>) enumClass.getSuperclass();
+ }
+ return enumClass;
}
return null;
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/JavaScriptScanner.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/JavaScriptScanner.java Wed Oct 16 11:23:46 2019 +0200
@@ -61,34 +61,8 @@
public Void visitAttribute(AttributeTree tree, Consumer<DocTreePath> f) {
String name = tree.getName().toString().toLowerCase(Locale.ENGLISH);
switch (name) {
- // See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler
- case "onabort": case "onblur": case "oncanplay": case "oncanplaythrough":
- case "onchange": case "onclick": case "oncontextmenu": case "ondblclick":
- case "ondrag": case "ondragend": case "ondragenter": case "ondragleave":
- case "ondragover": case "ondragstart": case "ondrop": case "ondurationchange":
- case "onemptied": case "onended": case "onerror": case "onfocus": case "oninput":
- case "oninvalid": case "onkeydown": case "onkeypress": case "onkeyup":
- case "onload": case "onloadeddata": case "onloadedmetadata": case "onloadstart":
- case "onmousedown": case "onmousemove": case "onmouseout": case "onmouseover":
- case "onmouseup": case "onmousewheel": case "onpause": case "onplay":
- case "onplaying": case "onprogress": case "onratechange": case "onreadystatechange":
- case "onreset": case "onscroll": case "onseeked": case "onseeking":
- case "onselect": case "onshow": case "onstalled": case "onsubmit": case "onsuspend":
- case "ontimeupdate": case "onvolumechange": case "onwaiting":
-
// See https://www.w3.org/TR/html4/sgml/dtd.html
- // Most of the attributes that take a %Script are also defined as event handlers
- // in HTML 5. The one exception is onunload.
- // case "onchange": case "onclick": case "ondblclick": case "onfocus":
- // case "onkeydown": case "onkeypress": case "onkeyup": case "onload":
- // case "onmousedown": case "onmousemove": case "onmouseout": case "onmouseover":
- // case "onmouseup": case "onreset": case "onselect": case "onsubmit":
- case "onunload":
- f.accept(getCurrentPath());
- break;
-
- // See https://www.w3.org/TR/html4/sgml/dtd.html
- // https://www.w3.org/TR/html5/
+ // https://www.w3.org/TR/html52/fullindex.html#attributes-table
// These are all the attributes that take a %URI or a valid URL potentially surrounded
// by spaces
case "action": case "cite": case "classid": case "codebase": case "data":
@@ -102,6 +76,14 @@
}
}
break;
+ // See https://www.w3.org/TR/html52/webappapis.html#events-event-handlers
+ // An event handler has a name, which always starts with "on" and is followed by
+ // the name of the event for which it is intended.
+ default:
+ if (name.startsWith("on")) {
+ f.accept(getCurrentPath());
+ }
+ break;
}
return super.visitAttribute(tree, f);
}
--- a/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c Wed Oct 16 11:23:46 2019 +0200
@@ -40,7 +40,6 @@
#include "sys.h"
/* How the options get to OnLoad: */
-#define XDEBUG "-Xdebug"
#define XRUN "-Xrunjdwp"
#define AGENTLIB "-agentlib:jdwp"
@@ -898,7 +897,7 @@
"--------\n"
" - The older " XRUN " interface can still be used, but will be removed in\n"
" a future release, for example:\n"
- " java " XDEBUG " " XRUN ":[help]|[<option>=<value>, ...]\n"
+ " java " XRUN ":[help]|[<option>=<value>, ...]\n"
));
#ifdef DEBUG
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, 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
@@ -82,6 +82,8 @@
}
} catch (final PatternSyntaxException e2) {
throwParserException("syntax", e2.getMessage());
+ } catch (StackOverflowError e3) {
+ throw new RuntimeException(e3);
}
}
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, 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
@@ -82,6 +82,8 @@
}
} catch (final PatternSyntaxException | JOniException e2) {
throwParserException("syntax", e2.getMessage());
+ } catch (StackOverflowError e3) {
+ throw new RuntimeException(e3);
}
}
--- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Wed Oct 16 01:16:12 2019 +0200
+++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -644,6 +644,7 @@
// renew if ticket is old.
Credentials newCred = renewCredentials(cred);
if (newCred != null) {
+ newCred.setProxy(cred.getProxy());
cred = newCred;
}
}
@@ -1070,6 +1071,10 @@
// create Kerberos Ticket
if (isInitiator) {
kerbTicket = Krb5Util.credsToTicket(cred);
+ if (cred.getProxy() != null) {
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetProxy(kerbTicket,Krb5Util.credsToTicket(cred.getProxy()));
+ }
}
if (storeKey && encKeys != null) {
--- a/test/hotspot/jtreg/TEST.groups Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/TEST.groups Wed Oct 16 11:23:46 2019 +0200
@@ -384,26 +384,26 @@
hotspot_tier2_runtime = \
runtime/ \
- serviceability/ \
-runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
-runtime/CompressedOops/UseCompressedOops.java \
-runtime/InvocationTests \
-runtime/Thread/TestThreadDumpMonitorContention.java \
-:tier1_runtime \
- -:tier1_serviceability \
-:hotspot_tier2_runtime_platform_agnostic \
-runtime/signal \
-runtime/NMT/MallocStressTest.java
+hotspot_tier2_serviceability = \
+ serviceability/ \
+ -:tier1_serviceability
+
hotspot_tier2_runtime_platform_agnostic = \
runtime/SelectionResolution \
-:tier1_runtime
hotspot_tier3_runtime = \
runtime/ \
- serviceability/ \
-:tier1_runtime \
- -:tier1_serviceability \
-:hotspot_tier2_runtime_platform_agnostic \
-:hotspot_tier2_runtime
--- a/test/hotspot/jtreg/TEST.quick-groups Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/TEST.quick-groups Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -1652,18 +1652,18 @@
vmTestbase/jit/escape/LockElision/MatMul/MatMul.java \
vmTestbase/jit/escape/LockCoarsening/LockCoarsening002/TestDescription.java \
vmTestbase/jit/exception/exception.java \
- vmTestbase/jit/graph/cgt0/cgt0.java \
- vmTestbase/jit/graph/cgt1/cgt1.java \
- vmTestbase/jit/graph/cgt2/cgt2.java \
- vmTestbase/jit/graph/cgt3/cgt3.java \
- vmTestbase/jit/graph/cgt4/cgt4.java \
- vmTestbase/jit/graph/cgt5/cgt5.java \
- vmTestbase/jit/graph/cgt6/cgt6.java \
- vmTestbase/jit/graph/cgt7/cgt7.java \
- vmTestbase/jit/graph/cgt8/cgt8.java \
- vmTestbase/jit/graph/cgt9/cgt9.java \
- vmTestbase/jit/graph/cgt10/cgt10.java \
- vmTestbase/jit/graph/cgt11/cgt11.java \
+ vmTestbase/jit/graph/cgt0.java \
+ vmTestbase/jit/graph/cgt1.java \
+ vmTestbase/jit/graph/cgt2.java \
+ vmTestbase/jit/graph/cgt3.java \
+ vmTestbase/jit/graph/cgt4.java \
+ vmTestbase/jit/graph/cgt5.java \
+ vmTestbase/jit/graph/cgt6.java \
+ vmTestbase/jit/graph/cgt7.java \
+ vmTestbase/jit/graph/cgt8.java \
+ vmTestbase/jit/graph/cgt9.java \
+ vmTestbase/jit/graph/cgt10.java \
+ vmTestbase/jit/graph/cgt11.java \
vmTestbase/jit/init/init01/init01.java \
vmTestbase/jit/init/init02/init02.java \
vmTestbase/jit/inline/inline003/inline003.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved.
+ * 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 8231988
+ * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
+ * compiler.loopopts.TestRemoveEmptyLoop
+ */
+
+package compiler.loopopts;
+
+public class TestRemoveEmptyLoop {
+
+ public void test() {
+ int i = 34;
+ for (; i > 0; i -= 11);
+ if (i < 0) {
+ // do nothing
+ } else {
+ throw new RuntimeException("Test failed.");
+ }
+ }
+
+ public static void main(String[] args) {
+ TestRemoveEmptyLoop _instance = new TestRemoveEmptyLoop();
+ for (int i = 0; i < 50000; i++) {
+ _instance.test();
+ }
+ System.out.println("Test passed.");
+ }
+
+}
--- a/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java Wed Oct 16 11:23:46 2019 +0200
@@ -45,7 +45,7 @@
}
int howLong = Integer.parseInt(args[0]);
- System.out.println(MAIN_METHOD_STARTED);
+ System.out.println(MAIN_METHOD_STARTED + ", argument is " + howLong);
for (int i=0; i < howLong; i++) {
SimpleEvent ev = new SimpleEvent();
@@ -56,6 +56,8 @@
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.print(".");
}
+
+ System.out.println("EventGeneratorLoop is coming to an end");
}
}
--- a/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java Wed Oct 16 11:23:46 2019 +0200
@@ -56,7 +56,7 @@
public class TestJcmdWithSideCar {
private static final String IMAGE_NAME = Common.imageName("jfr-jcmd");
private static final int TIME_TO_RUN_MAIN_PROCESS = (int) (30 * Utils.TIMEOUT_FACTOR); // seconds
- private static final long TIME_TO_WAIT_FOR_MAIN_METHOD_START = 5 * 1000; // milliseconds
+ private static final long TIME_TO_WAIT_FOR_MAIN_METHOD_START = 50 * 1000; // milliseconds
private static final String MAIN_CONTAINER_NAME = "test-container-main";
public static void main(String[] args) throws Exception {
@@ -198,6 +198,8 @@
.addDockerOpts("--volume", Paths.get(".").toAbsolutePath() + ":/workdir/")
.addJavaOpts("-XX:+UsePerfData")
.addClassOptions("" + TIME_TO_RUN_MAIN_PROCESS);
+ // avoid large Xmx
+ opts.appendTestJavaOptions = false;
List<String> cmd = DockerTestUtils.buildJavaCommand(opts);
ProcessBuilder pb = new ProcessBuilder(cmd);
@@ -232,9 +234,21 @@
}
public void waitForAndCheck(long timeout) throws Exception {
- waitFor(timeout);
- if (p.exitValue() != 0) {
- throw new RuntimeException("DockerThread stopped unexpectedly");
+ int exitValue = -1;
+ int retryCount = 3;
+
+ do {
+ waitFor(timeout);
+ try {
+ exitValue = p.exitValue();
+ } catch(IllegalThreadStateException ex) {
+ System.out.println("IllegalThreadStateException occured when calling exitValue()");
+ retryCount--;
+ }
+ } while (exitValue == -1 && retryCount > 0);
+
+ if (exitValue != 0) {
+ throw new RuntimeException("DockerThread stopped unexpectedly, non-zero exit value is " + exitValue);
}
}
--- a/test/hotspot/jtreg/gc/CriticalNativeArgs.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/gc/CriticalNativeArgs.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. and/or its affiliates.
*
* 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
@@ -28,7 +28,7 @@
* @key gc
* @bug 8199868
* @library /
- * @requires (os.arch =="x86_64" | os.arch == "amd64") & vm.gc.Epsilon & !vm.graal.enabled
+ * @requires (os.arch =="x86_64" | os.arch == "amd64" | os.arch=="x86" | os.arch=="i386") & vm.gc.Epsilon & !vm.graal.enabled
* @summary test argument unpacking nmethod wrapper of critical native method
* @run main/othervm/native -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xcomp -Xmx256M -XX:+CriticalJNINatives gc.CriticalNativeArgs
*/
@@ -38,7 +38,7 @@
* @key gc
* @bug 8199868
* @library /
- * @requires (os.arch =="x86_64" | os.arch == "amd64") & vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires (os.arch =="x86_64" | os.arch == "amd64" | os.arch=="x86" | os.arch=="i386") & 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: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
--- a/test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java Wed Oct 16 11:23:46 2019 +0200
@@ -26,7 +26,12 @@
* @key gc
* @requires vm.gc.Epsilon & !vm.graal.enabled
* @summary Basic sanity test for Epsilon
- * @run main/othervm -Xmx1g -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
+ * @run main/othervm -Xms128m -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
+ * @run main/othervm -Xms128m -Xmx1g -XX:-AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
+ * @run main/othervm -Xms128m -Xmx1g -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
+ * @run main/othervm -Xmx1g -XX:-AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
+ * @run main/othervm -Xmx1g -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.epsilon.TestAlwaysPretouch
*/
package gc.epsilon;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHumongousMoves.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+/*
+ * @test TestHumongousMoves
+ * @summary Check Shenandoah reacts on setting humongous moves correctly
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:-ShenandoahHumongousMoves
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestHumongousMoves
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g
+ * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
+ * -XX:+ShenandoahHumongousMoves
+ * -XX:-ShenandoahDegeneratedGC -XX:+ShenandoahVerify
+ * TestHumongousMoves
+ */
+
+import java.util.Random;
+
+public class TestHumongousMoves {
+
+ static final long TARGET_MB = Long.getLong("target", 10_000); // 10 Gb allocation
+
+ static volatile Object sink;
+
+ public static void main(String[] args) throws Exception {
+ final int min = 0;
+ final int max = 384 * 1024;
+ long count = TARGET_MB * 1024 * 1024 / (16 + 4 * (min + (max - min) / 2));
+
+ Random r = new Random();
+ for (long c = 0; c < count; c++) {
+ sink = new int[min + r.nextInt(max - min)];
+ }
+ }
+
+}
--- a/test/hotspot/jtreg/gc/stress/CriticalNativeStress.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/gc/stress/CriticalNativeStress.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. and/or its affiliates.
*
* 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
@@ -31,7 +31,7 @@
* @key gc
* @bug 8199868
* @library /
- * @requires (os.arch =="x86_64" | os.arch == "amd64") & vm.gc.Epsilon & !vm.graal.enabled
+ * @requires (os.arch =="x86_64" | os.arch == "amd64" | os.arch=="x86" | os.arch=="i386") & vm.gc.Epsilon & !vm.graal.enabled
* @summary test argument pinning by nmethod wrapper of critical native method
* @run main/othervm/native -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xcomp -Xmx1G -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
*/
@@ -41,7 +41,7 @@
* @key gc
* @bug 8199868
* @library /
- * @requires (os.arch =="x86_64" | os.arch == "amd64") & vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires (os.arch =="x86_64" | os.arch == "amd64" | os.arch=="x86" | os.arch=="i386") & 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: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
--- a/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java Wed Oct 16 11:23:46 2019 +0200
@@ -39,7 +39,7 @@
public class LotsOfClasses {
- public static void main(String[] args) throws Throwable {
+ public static void main(String[] args) throws Exception {
ArrayList<String> list = new ArrayList<>();
TestCommon.findAllClasses(list);
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java Wed Oct 16 11:23:46 2019 +0200
@@ -611,7 +611,7 @@
static Pattern pattern;
- static void findAllClasses(ArrayList<String> list) throws Throwable {
+ static void findAllClasses(ArrayList<String> list) throws Exception {
// Find all the classes in the jrt file system
pattern = Pattern.compile("/modules/[a-z.]*[a-z]+/([^-]*)[.]class");
FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
@@ -619,7 +619,7 @@
findAllClassesAtPath(base, list);
}
- private static void findAllClassesAtPath(Path p, ArrayList<String> list) throws Throwable {
+ private static void findAllClassesAtPath(Path p, ArrayList<String> list) throws Exception {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
for (Path entry: stream) {
Matcher matcher = pattern.matcher(entry.toString());
@@ -629,7 +629,7 @@
}
try {
findAllClassesAtPath(entry, list);
- } catch (Throwable t) {}
+ } catch (Exception ex) {}
}
}
}
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java Wed Oct 16 11:23:46 2019 +0200
@@ -45,22 +45,16 @@
public class DynamicLotsOfClasses extends DynamicArchiveTestBase {
- public static void main(String[] args) throws Throwable {
+ public static void main(String[] args) throws Exception {
runTest(DynamicLotsOfClasses::testDefaultBase);
}
static void testDefaultBase() throws Exception {
String topArchiveName = getNewArchiveName("top");
- try {
- doTest(topArchiveName);
- } catch (Throwable th) {
- System.out.println(th.toString());
- Exception ex = new Exception(th);
- throw ex;
- }
+ doTest(topArchiveName);
}
- private static void doTest(String topArchiveName) throws Throwable {
+ private static void doTest(String topArchiveName) throws Exception {
ArrayList<String> list = new ArrayList<>();
TestCommon.findAllClasses(list);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithCurrentThread/SuspendWithCurrentThread.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,222 @@
+/*
+ * 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 8231595
+ * @summary [TEST] develop a test case for SuspendThreadList including current thread
+ * @library /test/lib
+ * @compile SuspendWithCurrentThread.java
+ * @run main/othervm/native -agentlib:SuspendWithCurrentThread SuspendWithCurrentThread SuspenderIndex=first
+ * @run main/othervm/native -agentlib:SuspendWithCurrentThread SuspendWithCurrentThread SuspenderIndex=last
+ */
+
+import java.io.PrintStream;
+
+public class SuspendWithCurrentThread {
+ private static final String AGENT_LIB = "SuspendWithCurrentThread";
+ private static final String SUSPENDER_OPT = "SuspenderIndex=";
+ private static final int THREADS_COUNT = 10;
+
+ private static void log(String msg) { System.out.println(msg); }
+
+ private static native void registerTestedThreads(Thread[] threads);
+ private static native boolean checkTestedThreadsSuspended();
+ private static native void resumeTestedThreads();
+ private static native void releaseTestedThreadsInfo();
+
+ // The suspender thread index defines the thread which has to suspend
+ // the tested threads including itself with the JVMTI SuspendThreadList
+ private static int suspenderIndex;
+
+ public static void main(String args[]) throws Exception {
+ try {
+ System.loadLibrary(AGENT_LIB);
+ log("Loaded library: " + AGENT_LIB);
+ } catch (UnsatisfiedLinkError ule) {
+ log("Failed to load library: " + AGENT_LIB);
+ log("java.library.path: " + System.getProperty("java.library.path"));
+ throw ule;
+ }
+ if (args.length != 1) {
+ throw new RuntimeException("Main: wrong arguments count: " + args.length + ", expected: 1");
+ }
+ String arg = args[0];
+ if (arg.equals(SUSPENDER_OPT + "first")) {
+ suspenderIndex = 0;
+ } else if (arg.equals(SUSPENDER_OPT + "last")) {
+ suspenderIndex = THREADS_COUNT - 1;
+ } else {
+ throw new RuntimeException("Main: wrong argument: " + arg + ", expected: SuspenderIndex={first|last}");
+ }
+ log("Main: suspenderIndex: " + suspenderIndex);
+
+ SuspendWithCurrentThread test = new SuspendWithCurrentThread();
+ test.run();
+ }
+
+ private ThreadToSuspend[] startTestedThreads(int threadsCount) throws RuntimeException {
+ ThreadToSuspend[]threads = new ThreadToSuspend[threadsCount];
+
+ // create tested threads
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new ThreadToSuspend("ThreadToSuspend#" + i,
+ i == suspenderIndex // isSuspender
+ );
+ }
+ log("Main: starting tested threads");
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].start();
+ if (!threads[i].checkReady()) {
+ throw new RuntimeException("Main: unable to prepare tested thread: " + threads[i]);
+ }
+ }
+ log("Main: tested threads started");
+
+ registerTestedThreads(threads);
+ return threads;
+ }
+
+ private boolean checkSuspendedStatus() throws RuntimeException {
+ log("Main: checking all tested threads have been suspended");
+ return checkTestedThreadsSuspended();
+ }
+
+ /* The test does the following steps:
+ * - main thread starts several (THREADS_COUNT) ThreadToSuspend tested threads
+ * - main thread waits for threads to be ready with the thread.checkReady()
+ * - main thread registers tested threads within the native agent library
+ * with the native method registerTestedThreads()
+ * - main thread triggers the suspender tested thread with the
+ * ThreadToSuspend.setAllThreadsReady() to suspend tested threads
+ * - suspender thread suspends tested threads including itself with the native
+ * method suspendTestedThreads() (uses the JVMTI SuspendThreadList function)
+ * - main thread checks tested threads suspended status with the native method
+ * checkSuspendedStatus(); the tested threads are expected to have suspended status
+ * - main thread resumes tested threads with the native method resumeTestedThreads()
+ * - main thread releases tested threads with the native method releaseTestedThreads()
+ * - main thread triggers the tested threads to finish with the thread.letFinish()
+ */
+ private void run() throws Exception {
+ ThreadToSuspend[] threads = null; // tested threads
+
+ log("Main: started");
+ try {
+ threads = startTestedThreads(THREADS_COUNT);
+
+ log("Main: trigger " + threads[suspenderIndex].getName() +
+ " to suspend all tested threads including itself");
+ ThreadToSuspend.setAllThreadsReady();
+
+ if (!checkSuspendedStatus()) {
+ throw new RuntimeException("Main: FAILED status returned from checkTestedThreadsSuspended");
+ }
+
+ log("Main: resuming all tested threads");
+ resumeTestedThreads();
+ } finally {
+ // let threads to finish
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].letFinish();
+ }
+ log("Main: tested threads finished");
+ }
+
+ // wait for threads to finish
+ log("Main: joining tested threads");
+ try {
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].join();
+ }
+ log("Main: tested thread joined");
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ log("Main: releasing tested threads native info");
+ releaseTestedThreadsInfo();
+
+ log("Main: finished");
+ }
+}
+
+/* =================================================================== */
+
+// tested threads
+class ThreadToSuspend extends Thread {
+ private static void log(String msg) { System.out.println(msg); }
+
+ private static native void init();
+ private static native void suspendTestedThreads();
+ private static volatile boolean allThreadsReady = false;
+
+ public static void setAllThreadsReady() {
+ allThreadsReady = true;
+ }
+
+ private volatile boolean threadReady = false;
+ private volatile boolean shouldFinish = false;
+ private boolean isSuspender = false;
+
+ // make thread with specific name
+ public ThreadToSuspend(String name, boolean isSuspender) {
+ super(name);
+ this.isSuspender = isSuspender;
+ }
+
+ // run thread continuously
+ public void run() {
+ boolean needSuspend = true;
+
+ if (isSuspender) {
+ init();
+ }
+ threadReady = true;
+
+ // run in a loop
+ while (!shouldFinish) {
+ if (isSuspender && needSuspend && allThreadsReady) {
+ log(getName() + ": before suspending all tested threads including myself");
+ needSuspend = false;
+ suspendTestedThreads();
+ log(getName() + ": after suspending all tested threads including myself");
+ }
+ }
+ }
+
+ // check if thread is ready
+ public boolean checkReady() {
+ try {
+ while (!threadReady) {
+ sleep(1);
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("checkReady: sleep was interrupted\n\t" + e);
+ }
+ return threadReady;
+ }
+
+ // let thread to finish
+ public void letFinish() {
+ shouldFinish = true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithCurrentThread/libSuspendWithCurrentThread.cpp Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,209 @@
+/*
+ * 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 <string.h>
+#include "jvmti.h"
+
+extern "C" {
+
+static jvmtiEnv* jvmti = NULL;
+static jthread* threads = NULL;
+static jsize threads_count = 0;
+static jrawMonitorID agent_monitor = NULL;
+
+#define LOG(...) \
+ do { \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
+ fflush(stdout); \
+ } while (0)
+
+static void
+check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) {
+ if (err != JVMTI_ERROR_NONE) {
+ LOG("check_jvmti_status: JVMTI function returned error: %d", err);
+ jni->FatalError(msg);
+ }
+}
+
+static void
+agent_lock(JNIEnv* jni) {
+ jvmtiError err = jvmti->RawMonitorEnter(agent_monitor);
+ check_jvmti_status(jni, err, "monitor_enter: error in JVMTI RawMonitorEnter");
+}
+
+static void
+agent_unlock(JNIEnv* jni) {
+ jvmtiError err = jvmti->RawMonitorExit(agent_monitor);
+ check_jvmti_status(jni, err, "monitor_exit: error in JVMTI RawMonitorExit");
+}
+
+JNIEXPORT void JNICALL
+Java_SuspendWithCurrentThread_registerTestedThreads(JNIEnv *jni, jclass cls, jobjectArray threadsArr) {
+ LOG("\nregisterTestedThreads: started");
+ threads_count = jni->GetArrayLength(threadsArr);
+
+ jvmtiError err = jvmti->Allocate((threads_count * sizeof(jthread)),
+ (unsigned char**)&threads);
+ check_jvmti_status(jni, err, "registerTestedThreads: error in JVMTI Allocate threads array");
+
+ for (int i = 0; i < threads_count; i++) {
+ jobject elem = jni->GetObjectArrayElement(threadsArr, i);
+ threads[i] = (jthread)jni->NewGlobalRef(elem);
+ }
+ LOG("registerTestedThreads: finished\n");
+}
+
+/* This function is executed on the suspender thread, not the Main thread */
+JNIEXPORT void JNICALL
+Java_ThreadToSuspend_init(JNIEnv *jni, jclass cls) {
+ jvmtiError err = jvmti->CreateRawMonitor("Agent monitor", &agent_monitor);
+ check_jvmti_status(jni, err, "Java_ThreadToSuspend_init: error in JVMTI CreateRawMonitor");
+
+ // Main thread has to wait for the suspender thread to complete tested threads suspension
+ agent_lock(jni);
+}
+
+/* This function is executed on the suspender thread which is not Main thread */
+JNIEXPORT void JNICALL
+Java_ThreadToSuspend_suspendTestedThreads(JNIEnv *jni, jclass cls) {
+ jvmtiError* results = NULL;
+ jvmtiError err;
+
+ LOG("\nsuspendTestedThreads: started");
+ err = jvmti->Allocate((threads_count * sizeof(jvmtiError)),
+ (unsigned char**)&results);
+ check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI Allocate results array");
+
+ LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
+ err = jvmti->SuspendThreadList(threads_count, threads, results);
+ check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI SuspendThreadList");
+
+ LOG("suspendTestedThreads: check and print SuspendThreadList results:");
+ for (int i = 0; i < threads_count; i++) {
+ LOG(" thread #%d: (%d)", i, (int)results[i]);
+ check_jvmti_status(jni, results[i], "suspendTestedThreads: error in SuspendThreadList results[i]");
+ }
+ LOG("suspendTestedThreads: finished\n");
+
+ // Allow the Main thread to inspect the result of tested threads suspension
+ agent_unlock(jni);
+
+ err = jvmti->Deallocate((unsigned char*)results);
+ check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI Deallocate results");
+}
+
+JNIEXPORT jboolean JNICALL
+Java_SuspendWithCurrentThread_checkTestedThreadsSuspended(JNIEnv *jni, jclass cls) {
+ LOG("checkTestedThreadsSuspended: started");
+
+ // Block until the suspender thread competes the tested threads suspension
+ agent_lock(jni);
+ agent_unlock(jni);
+
+ for (int i = 0; i < threads_count; i++) {
+ jint state = 0;
+ jvmtiError err = jvmti->GetThreadState(threads[i], &state);
+ check_jvmti_status(jni, err, "checkTestedThreadsSuspended: error in GetThreadState");
+
+ if ((state & JVMTI_THREAD_STATE_SUSPENDED) == 0) {
+ LOG("thread #%d has not been suspended yet: "
+ "# state: (%#x)", i, (int)state);
+ jni->FatalError("checkTestedThreadsSuspended: error: expected all tested threads suspended");
+ }
+ }
+ LOG("checkTestedThreadsSuspended: finished\n");
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL
+Java_SuspendWithCurrentThread_resumeTestedThreads(JNIEnv *jni, jclass cls) {
+ jvmtiError* results = NULL;
+ jvmtiError err;
+
+ LOG("\nresumeTestedThreads: started");
+ err = jvmti->Allocate((threads_count * sizeof(jvmtiError)),
+ (unsigned char**)&results);
+ check_jvmti_status(jni, err, "resumeTestedThreads: error in JVMTI Allocate results array");
+
+ LOG("resumeTestedThreads: before JVMTI ResumeThreadList");
+ err = jvmti->ResumeThreadList(threads_count, threads, results);
+ check_jvmti_status(jni, err, "resumeTestedThreads: error in ResumeThreadList");
+
+ LOG("resumeTestedThreads: check and print ResumeThreadList results:");
+ for (int i = 0; i < threads_count; i++) {
+ LOG(" thread #%d: (%d)", i, (int)results[i]);
+ check_jvmti_status(jni, results[i], "resumeTestedThreads: error in ResumeThreadList results[i]");
+ }
+
+ err = jvmti->Deallocate((unsigned char*)results);
+ check_jvmti_status(jni, err, "resumeTestedThreads: error in JVMTI Deallocate results");
+
+ LOG("resumeTestedThreads: finished\n");
+}
+
+JNIEXPORT void JNICALL
+Java_SuspendWithCurrentThread_releaseTestedThreadsInfo(JNIEnv *jni, jclass cls) {
+ jvmtiError err;
+
+ LOG("\nreleaseTestedThreadsInfo: started");
+ err = jvmti->DestroyRawMonitor(agent_monitor);
+ check_jvmti_status(jni, err, "releaseTestedThreadsInfo: error in JVMTI DestroyRawMonitor");
+
+ for (int i = 0; i < threads_count; i++) {
+ if (threads[i] != NULL) {
+ jni->DeleteGlobalRef(threads[i]);
+ }
+ }
+ err = jvmti->Deallocate((unsigned char*)threads);
+ check_jvmti_status(jni, err, "releaseTestedThreadsInfo: error in JVMTI Deallocate threads");
+
+ LOG("releaseTestedThreadsInfo: finished\n");
+}
+
+
+/** Agent library initialization. */
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+ LOG("\nAgent_OnLoad started");
+
+ // create JVMTI environment
+ if (jvm->GetEnv((void **) (&jvmti), JVMTI_VERSION) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ // add specific capabilities for suspending thread
+ jvmtiCapabilities suspendCaps;
+ memset(&suspendCaps, 0, sizeof(suspendCaps));
+ suspendCaps.can_suspend = 1;
+
+ jvmtiError err = jvmti->AddCapabilities(&suspendCaps);
+ if (err != JVMTI_ERROR_NONE) {
+ return JNI_ERR;
+ }
+ LOG("Agent_OnLoad finished\n");
+ return JNI_OK;
+}
+
+}
--- a/test/hotspot/jtreg/serviceability/logging/TestQuotedLogOutputs.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/serviceability/logging/TestQuotedLogOutputs.java Wed Oct 16 11:23:46 2019 +0200
@@ -26,6 +26,7 @@
* @summary Ensure proper parsing of quoted output names for -Xlog arguments.
* @modules java.base/jdk.internal.misc
* @library /test/lib
+ * @run main/othervm TestQuotedLogOutputs
*/
import java.io.File;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/**
+ * @test
+ * @bug 8196969
+ * @requires vm.hasSAandCanAttach
+ * @library /test/lib
+ * @run main/othervm ClhsdbJstackXcompStress
+ */
+public class ClhsdbJstackXcompStress {
+
+ private static final int MAX_ITERATIONS = 20;
+ private static final boolean DEBUG = false;
+
+ private static boolean isMatchCompiledFrame(List<String> output) {
+ List<String> filtered = output.stream().filter( s -> s.contains("Compiled frame"))
+ .collect(Collectors.toList());
+ System.out.println("DEBUG: " + filtered);
+ return !filtered.isEmpty() &&
+ filtered.stream().anyMatch( s -> s.contains("LingeredAppWithRecComputation") );
+ }
+
+ private static void runJstackInLoop(LingeredApp app) throws Exception {
+ boolean anyMatchedCompiledFrame = false;
+ for (int i = 0; i < MAX_ITERATIONS; i++) {
+ JDKToolLauncher launcher = JDKToolLauncher
+ .createUsingTestJDK("jhsdb");
+ launcher.addToolArg("jstack");
+ launcher.addToolArg("--pid");
+ launcher.addToolArg(Long.toString(app.getPid()));
+
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command(launcher.getCommand());
+ Process jhsdb = pb.start();
+ OutputAnalyzer out = new OutputAnalyzer(jhsdb);
+
+ jhsdb.waitFor();
+
+ if (DEBUG) {
+ System.out.println(out.getStdout());
+ System.err.println(out.getStderr());
+ }
+
+ out.stderrShouldBeEmpty(); // NPE's are reported on the err stream
+ out.stdoutShouldNotContain("Error occurred during stack walking:");
+ out.stdoutShouldContain(LingeredAppWithRecComputation.THREAD_NAME);
+ List<String> stdoutList = Arrays.asList(out.getStdout().split("\\R"));
+ anyMatchedCompiledFrame = anyMatchedCompiledFrame || isMatchCompiledFrame(stdoutList);
+ }
+ if (!anyMatchedCompiledFrame) {
+ throw new RuntimeException("Expected jstack output to contain 'Compiled frame'");
+ }
+ System.out.println("DEBUG: jhsdb jstack did not throw NPE, as expected.");
+ }
+
+ public static void main(String... args) throws Exception {
+ LingeredApp app = null;
+ try {
+ List<String> vmArgs = List.of("-Xcomp",
+ "-XX:CompileCommand=dontinline,LingeredAppWithRecComputation.factorial",
+ "-XX:CompileCommand=compileonly,LingeredAppWithRecComputation.testLoop",
+ "-XX:CompileCommand=compileonly,LingeredAppWithRecComputation.factorial");
+ app = new LingeredAppWithRecComputation();
+ LingeredApp.startApp(vmArgs, app);
+ System.out.println("Started LingeredAppWithRecComputation with pid " + app.getPid());
+ runJstackInLoop(app);
+ System.out.println("Test Completed");
+ } catch (Throwable e) {
+ e.printStackTrace();
+ throw e;
+ } finally {
+ LingeredApp.stopApp(app);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithRecComputation.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.apps.LingeredApp;
+
+public class LingeredAppWithRecComputation extends LingeredApp {
+
+ public static final String THREAD_NAME = "LingeredAppWithRecComputation.factorial()";
+
+ private long factorial(int n) {
+ if (n <= 1) {
+ return 1;
+ }
+ if (n == 2) {
+ return 2;
+ }
+ return n * factorial(n - 1);
+ }
+
+ public void testLoop() {
+ long result = 0;
+ long[] lastNResults = new long[20];
+ int i = 0;
+ int j = 0;
+ while (true) {
+ result = factorial(i);
+ lastNResults[j] = result;
+ if (i % 12 == 0) {
+ i = -1; // reset i
+ }
+ if (j % 19 == 0) {
+ j = -1; // reset j
+ }
+ i++; j++;
+ }
+ }
+
+ public static void main(String args[]) {
+ LingeredAppWithRecComputation app = new LingeredAppWithRecComputation();
+ Thread factorial = new Thread(() -> {
+ app.testLoop();
+ });
+ factorial.setName(THREAD_NAME);
+ factorial.start();
+ LingeredApp.main(args);
+ }
+ }
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/CGT.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/CGT.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -22,245 +22,219 @@
*/
package jit.graph;
-import java.util.*;
+
+import jdk.test.lib.Utils;
+import jtreg.SkippedException;
import nsk.share.TestFailure;
import nsk.share.test.StressOptions;
-class CGT extends Thread
-{
- private static StressOptions stressOptions = new StressOptions();
- private final static String version = "1.0";
- private static String ClistPath = "";
+import java.lang.reflect.InvocationTargetException;
+import java.util.Vector;
- private static long finishTime;
+public class CGT {
+ private static StressOptions stressOptions = new StressOptions();
+ private static String ClistPath = "";
+ private static long finishTime;
+
+ private final Vector summation = new Vector(100000);
+ private final Vector idList = new Vector(100000);
- public CGT( String[] args )
- {
- parse (args);
- Globals.initialize(ClistPath);
- outputStats (args);
- }
+ public CGT(String[] args) {
+ parse(args);
+ Globals.initialize(ClistPath);
+ outputStats(args);
+ }
-
- public static void main( String[] args )
- {
- stressOptions.parseCommandLine(args);
- CGT jnimt = new CGT(args);
- jnimt.start();
- }
+ public static void main(String[] args) {
+ stressOptions.parseCommandLine(args);
+ new CGT(args).run();
+ }
- public void outputStats( String[] args )
- {
- System.out.println("CGT command line options:");
- for (int i=0; i < args.length; ++i )
- System.out.println("# " + args[i] );
-
- System.out.println();
+ public void outputStats(String[] args) {
+ System.out.println("CGT command line options:");
+ for (String arg : args) {
+ System.out.println("# " + arg);
+ }
- System.out.println("CGT parameters");
- System.out.println("Seed: " +Globals.RANDOM_SEED);
- System.out.println("Number of Threads: " +Globals.NUM_THREADS);
- System.out.println("Number of Random Loop iterations: " + Globals.RANDOM_LOOP);
- System.out.println("Number of Static Loop iterations: " + Globals.STATIC_LOOP);
- System.out.println("Max number of Methods in the Graph: " + Globals.NUM_TEST_CLASSES);
- System.out.println("Verbose function calls: " + Globals.VERBOSE);
+ System.out.println();
- System.out.println();
- }
-
- public void run()
- {
- finishTime = System.currentTimeMillis() + stressOptions.getTime() * 1000;
+ System.out.println("CGT parameters");
+ System.out.println("Seed: " + Utils.SEED);
+ System.out.println("Number of Random Loop iterations: " + Globals.RANDOM_LOOP);
+ System.out.println("Number of Static Loop iterations: " + Globals.STATIC_LOOP);
+ System.out.println("Max number of Methods in the Graph: " + Globals.NUM_TEST_CLASSES);
+ System.out.println("Verbose function calls: " + Globals.VERBOSE);
- for (int i = 0; i< Globals.NUM_THREADS; i++)
- new CGTThread("CGT Thread " + i).start();
- }
+ System.out.println();
+ }
- public static boolean shouldFinish()
- {
- return System.currentTimeMillis() >= finishTime;
- }
+ public void run() {
+ finishTime = System.currentTimeMillis() + stressOptions.getTime() * 1000;
+ Long numFcalls = Globals.RANDOM_LOOP - 1;
+ Integer staticFcalls = Globals.STATIC_LOOP;
+ MethodData methodCallStr = Globals.nextRandomMethod();
+ Globals.addFunctionIDToVector(methodCallStr.id, idList);
+ Throwable invocationExcept;
- public void parse (String args[])
- {
- for (int i = 0; i<args.length; i++)
- {
- if ((args[i].equalsIgnoreCase("-help")) || (args[i].equalsIgnoreCase("-h")) || (args[i].equalsIgnoreCase("-?")))
- {
- usage ();
- }
- else if (args[i].equalsIgnoreCase("-version"))
- {
- version();
- }
- else if (args[i].equalsIgnoreCase("-seed"))
- {
- int argIndex = i+1;
- if (argIndex < args.length)
- {
- try
- {
- Globals.RANDOM_SEED = Math.abs(Long.parseLong(args[argIndex]));
- }
- catch (NumberFormatException e)
- {
- System.out.println("Improper Argument: " + args[i] + " " + args[argIndex]);
- usage ();
- }
- i++;
- }
- else
- {
- System.out.println("Improper Argument: " + args[i]);
- usage ();
- }
+ try {
+ methodCallStr.nextMethod.invoke(methodCallStr.instance, summation, idList, numFcalls, staticFcalls);
+ } catch (IllegalAccessException e) {
+ throw new TestFailure("Illegal Access Exception", e);
+ } catch (InvocationTargetException e) {
+ System.out.println("Invocation Target Exception");
+ invocationExcept = e.getTargetException();
+ System.out.println(invocationExcept);
+ if (invocationExcept.getClass() == e.getClass()) {
+ System.out.println("Processing Exception Invocation Target Exception");
+ while (invocationExcept.getClass() == e.getClass()) {
+ invocationExcept = ((InvocationTargetException) invocationExcept).getTargetException();
+ }
+ System.out.println(invocationExcept);
+ }
+ if (invocationExcept instanceof StackOverflowError) {
+ throw new SkippedException("stack overflow: skipping verification.", invocationExcept);
+ } else if (invocationExcept instanceof OutOfMemoryError) {
+ throw new SkippedException("test devoured heap ;), skipping verification.", invocationExcept);
+ } else {
+ throw new TestFailure(invocationExcept);
+ }
+ }
+
+ verify();
+ }
- }
- else if ((args[i].equalsIgnoreCase("-thread")) || (args[i].equalsIgnoreCase("-threads")))
- {
- int argIndex = i+1;
- if (argIndex < args.length)
- {
- try
- {
- Globals.NUM_THREADS = Math.abs(Integer.parseInt(args[argIndex])) * stressOptions.getThreadsFactor();
- }
- catch (NumberFormatException e)
- {
- System.out.println("Improper Argument: " + args[i] + " " + args[argIndex]);
- usage ();
- }
- if(Globals.NUM_THREADS == 0)
- Globals.NUM_THREADS = 1;
- i++;
- }
- else
- {
- System.out.println("Improper Argument: " + args[i]);
- usage ();
- }
+ private void verify() {
+ long oldsum = 0;
+ long newsum;
+ System.out.println("begin call stack validation");
+ if (summation.size() != idList.size()) {
+ throw new TestFailure("Vector Length's Do Not Match, VERIFY ERROR : Summation Element Count = " + summation.size() + " ID Element Count = " + idList.size());
+ }
+ long vectorSize = summation.size();
+
+ while (!summation.isEmpty()) {
+ if (CGT.shouldFinish()) {
+ throw new SkippedException("skipping verification due to timeout");
+ }
+
+ newsum = (Long) summation.firstElement();
+ summation.removeElementAt(0);
+
+ int functionID = (Integer) idList.firstElement();
+ idList.removeElementAt(0);
+
+ if ((newsum - oldsum) != (functionID)) {
+ throw new TestFailure("Function Call structure invalid, VERIFY ERROR. Expected = " + (newsum - oldsum) + " Actual = " + functionID);
+ }
+ oldsum = newsum;
+ }
+
+ System.out.println("function call structure validated successfully (" + vectorSize + " calls validated)");
+ }
- }
- else if (args[i].equalsIgnoreCase("-staticLoop"))
- {
- int argIndex = i+1;
- if (argIndex < args.length)
- {
- try
- {
- Globals.STATIC_LOOP = Math.abs(Integer.parseInt(args[argIndex])) * stressOptions.getIterationsFactor();
- }
- catch (NumberFormatException e)
- {
- System.out.println("Improper Argument: " + args[i] + " " + args[argIndex]);
- usage ();
- }
- i++;
- }
- else
- {
- System.out.println("Improper Argument: " + args[i]);
- usage ();
- }
+ public static boolean shouldFinish() {
+ return System.currentTimeMillis() >= finishTime;
+ }
- }
- else if (args[i].equalsIgnoreCase("-randomLoop"))
- {
- int argIndex = i+1;
- if (argIndex < args.length)
- {
- try
- {
- Globals.RANDOM_LOOP = Math.abs(Long.parseLong(args[argIndex])) * stressOptions.getIterationsFactor();
- }
- catch (NumberFormatException e)
- {
- System.out.println("Improper Argument: " + args[i] + " " + args[argIndex]);
- usage ();
- }
- i++;
- }
- else
- {
- System.out.println("Improper Argument: " + args[i]);
- usage ();
- }
+ public void parse(String args[]) {
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i].toLowerCase();
+ switch (arg) {
+ case "-help":
+ case "-h":
+ case "-?": {
+ usage();
+ System.exit(1);
+ break;
+ }
+ case "-staticloop": {
+ int argIndex = i + 1;
+ if (argIndex < args.length) {
+ try {
+ Globals.STATIC_LOOP = Math.abs(Integer.parseInt(args[argIndex])) * stressOptions.getIterationsFactor();
+ } catch (NumberFormatException e) {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i] + " " + args[argIndex], e);
+ }
+ i++;
+ } else {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i]);
+ }
+ break;
+ }
+ case "-randomloop": {
+ int argIndex = i + 1;
+ if (argIndex < args.length) {
+ try {
+ Globals.RANDOM_LOOP = Math.abs(Long.parseLong(args[argIndex])) * stressOptions.getIterationsFactor();
+ } catch (NumberFormatException e) {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i] + " " + args[argIndex], e);
+ }
+ i++;
+ } else {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i]);
- }
- else if (args[i].equalsIgnoreCase("-numTestClass"))
- {
- int argIndex = i+1;
- if (argIndex < args.length)
- {
- try
- {
- Globals.NUM_TEST_CLASSES = Math.abs(Integer.parseInt(args[argIndex]));
- }
- catch (NumberFormatException e)
- {
- System.out.println("Improper Argument: " + args[i] + " " + args[argIndex]);
- usage ();
- }
- i++;
- }
- else
- {
- System.out.println("Improper Argument: " + args[i]);
- usage ();
- }
+ }
+ break;
+ }
+ case "-numtestclass": {
+ int argIndex = i + 1;
+ if (argIndex < args.length) {
+ try {
+ Globals.NUM_TEST_CLASSES = Math.abs(Integer.parseInt(args[argIndex]));
+ } catch (NumberFormatException e) {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i] + " " + args[argIndex], e);
+ }
+ i++;
+ } else {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i]);
+ }
+ break;
+ }
+ case "-verbose":
+ case "-v": {
+ Globals.VERBOSE = true;
+ break;
+ }
+ case "-path": {
+ int argIndex = i + 1;
+ if (argIndex < args.length) {
+ ClistPath = args[argIndex];
+ i++;
+ } else {
+ usage();
+ throw new Error("TESTBUG: Improper Argument: " + args[i]);
+ }
+ break;
+ }
+ default: {
+ if (!arg.startsWith("-stress")) {
+ usage();
+ throw new Error("TESTBUG: Invalid Argument: " + args[i]);
+ }
+ }
+ }
+ }
- }
- else if (args[i].equalsIgnoreCase("-v") || args[i].equalsIgnoreCase("-verbose"))
- {
- Globals.VERBOSE = true;
- }
- else if (args[i].equalsIgnoreCase("-path"))
- {
- int argIndex = i+1;
- if (argIndex < args.length)
- {
- ClistPath = args[argIndex];
- i++;
- }
- else
- {
- System.out.println("Improper Argument: " + args[i]);
- usage ();
- }
- }
- else if (args[i].startsWith("-stress"))
- {
- break;
- }
- else
- {
- System.out.println("Invalid Argument: " + args[i]);
- usage ();
- }
+ if ("".equals(ClistPath)) {
+ usage();
+ throw new Error("TESTBUG: class list path not defined");
}
- if (ClistPath.equals(""))
- {
- System.out.println("class list path not defined");
- usage();
- }
- }
+ }
- public void usage ()
- {
- System.out.println("usage: java CGT [options]");
- System.out.println(" -help prints out this message");
- System.out.println(" -numTestClass # limits the number of \"Test Methods\" to #");
- System.out.println(" -randomcLoop # # of random function calls");
- System.out.println(" -seed # uses the specified seed rather than the System Time");
- System.out.println(" -staticLoop # # of non-random static function calls");
- System.out.println(" -threads # # number of test threads, NOTE: no maximum value");
- System.out.println(" -version print out the tool version");
- System.out.println(" -v -verbose turn on verbose mode");
- throw new TestFailure(" -path <path to classlist> required, argument so program can find classes");
- }
-
- public void version ()
- {
- throw new TestFailure("CGT version = " + version);
- }
+ public void usage() {
+ System.out.println("usage: java CGT [options]");
+ System.out.println(" -help prints out this message");
+ System.out.println(" -numTestClass # limits the number of \"Test Methods\" to #");
+ System.out.println(" -randomcLoop # # of random function calls");
+ System.out.println(" -seed # uses the specified seed rather than the System Time");
+ System.out.println(" -staticLoop # # of non-random static function calls");
+ System.out.println(" -v -verbose turn on verbose mode");
+ System.out.println(" -path <path to classlist> required, argument so program can find classes");
+ }
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/CGTThread.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 1998, 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.
- */
-
-package jit.graph;
-import java.util.*;
-import java.lang.*;
-import java.lang.reflect.*;
-import nsk.share.TestFailure;
-
-class CGTThread extends Thread
-{
- private String ThreadName = null;
- private Vector Sumation = new Vector(100000);
- private Vector IDlist = new Vector(100000);
-
-
- CGTThread( String name )
- {
- ThreadName = name;
- setName(name);
- }
-
-
- public void run()
- {
- if (Globals.VERBOSE)
- System.out.println("\t\t" + Thread.currentThread().getName() + " started");
- Long numFcalls = new Long(Globals.RANDOM_LOOP - 1);
- Integer staticFcalls = new Integer(Globals.STATIC_LOOP);
- MethodData methodCallStr = Globals.nextRandomMethod();
- Globals.addFunctionIDToVector(methodCallStr.id, IDlist);
- Throwable invocationExcept = null;
-
- boolean skipVerify = false;
-
- try
- {
- methodCallStr.nextMethod.invoke(methodCallStr.instance, new Object []{Sumation, IDlist, numFcalls, staticFcalls});
- }
- catch (IllegalAccessException iax)
- {
- throw new TestFailure("Illegal Access Exception");
- }
- catch (InvocationTargetException itx)
- {
- System.out.println("Invocation Target Exception");
- invocationExcept = itx.getTargetException();
- System.out.println(invocationExcept);
- if (invocationExcept.getClass() == itx.getClass())
- {
- System.out.println("Processing Exception Invocation Target Exception");
- while (invocationExcept.getClass() == itx.getClass())
- invocationExcept = ((InvocationTargetException)invocationExcept).getTargetException();
- System.out.println(invocationExcept);
- }
- if (invocationExcept instanceof StackOverflowError)
- //StackOverFlow is not a failure
- {
- System.out.println("Warning: stack overflow: skipping verification...");
- skipVerify = true;
- }
- else if (invocationExcept instanceof OutOfMemoryError)
- //OutOfMemoryError is not a failure
- {
- System.out.println("Warning: test devoured heap ;), skipping verification...");
- skipVerify = true;
- }
- else
- {
- invocationExcept.printStackTrace();
- System.exit(1);
- }
- }
-
- if( !skipVerify )
- verify(Sumation, IDlist);
- }
-
- void verify(Vector Sum, Vector ID)
- {
- long oldsum = 0;
- long newsum;
- System.out.println(ThreadName + " has begun call stack validation");
- if (Sum.size() != ID.size())
- {
- System.out.println("Vector Length's Do Not Match, VERIFY ERROR");
- System.out.println("Thread Name: " + ThreadName);
- throw new TestFailure("Sumation Element Count = " + Sum.size() + " ID Element Count = " +ID.size());
- }
- long vectorSize = Sum.size();
- while (!Sum.isEmpty())
- {
- if (CGT.shouldFinish())
- {
- System.out.println(Thread.currentThread().getName() + ": skipping verification due to timeout");
- return;
- }
-
- newsum = ((Long)Sum.firstElement()).longValue();
- Sum.removeElementAt(0);
-
- int functionID = ((Integer)ID.firstElement()).intValue();
- ID.removeElementAt(0);
-
- if ((newsum - oldsum) != (functionID))
- {
- System.out.println("Function Call structure invalid, VERIFY ERROR");
- System.out.println("Thread Name: " + ThreadName);
- System.out.println("Expected = " +(newsum - oldsum) + " Actual = " +functionID);
- throw new TestFailure("Test failed.");
-// System.exit(1);
- }
- oldsum = newsum;
- }
- Globals.decNumThreads();
- System.out.println(ThreadName + "'s function call structure validated succesfully ("+vectorSize+" calls validated)");
- }
-
-}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/Globals.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/Globals.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -22,263 +22,200 @@
*/
package jit.graph;
-import java.io.*;
-import java.util.*;
-import java.lang.*;
-import java.lang.reflect.*;
+
+import jdk.test.lib.Utils;
import nsk.share.TestFailure;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Random;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+public final class Globals {
+
-public final class Globals
-{
- // Minimum and Maximum number of threads
- public static int NUM_THREADS = 1;
- public static long RANDOM_SEED = System.currentTimeMillis();
- public static int STATIC_LOOP = 0;
- public static int NUM_TEST_CLASSES = 7;
- public static long RANDOM_LOOP = 100;
- public static boolean VERBOSE = false;
- private static Random indexGenerator = null;
+ public static int STATIC_LOOP = 0;
+ public static int NUM_TEST_CLASSES = 7;
+ public static long RANDOM_LOOP = 100;
+ public static boolean VERBOSE = false;
- //private static TestLoader CGTTestLoader = null;
- private static String [] ClassArray = null;
- private static Class [] ClassInstanceArray = null;
- private static int maxClassIndex = 0;
+ private static final Random indexGenerator = Utils.getRandomInstance();
+ private static String[] ClassArray = null;
+ private static Class[] ClassInstanceArray = null;
+ private static int maxClassIndex = 0;
- private static String [] MethodName_Array = null;
- private static Method [] MethodInstance_Array = null;
+ private static String[] MethodName_Array = null;
+ private static Method[] MethodInstance_Array = null;
- //Should be prime, so that odds of an incorrect verification reduced
- public static int [] MethodID_Array = null;
-
-
- //Number of threads will be reduced as threads finish
- public static synchronized void decNumThreads(){NUM_THREADS--;};
-
- public static synchronized void initialize(String testListPath)
- {
+ // Should be prime, so that odds of an incorrect verification reduced
+ public static int[] MethodID_Array = null;
- File td = new File (testListPath);
- if (!td.exists())
- {
- System.err.println("File " + testListPath + " Not found");
- System.exit(1);
- }
- if (!td.isFile())
- {
- System.err.println(testListPath + " Must be a File");
- System.exit(1);
- }
+ public static synchronized void initialize(String testListPath) {
+ File td = new File(testListPath);
+ if (!td.exists()) {
+ throw new Error("TESTBUG: File " + testListPath + " Not found");
+ }
+
+ if (!td.isFile()) {
+ throw new Error("TESTBUG: " + testListPath + " Must be a File");
+ }
BufferedReader classList = null;
-
- try
- {
- classList = new BufferedReader(new FileReader(td));
- }
- catch (FileNotFoundException fnfx)
- {
- System.err.println("Error finding Classlist");
- System.exit(1);
- }
-
- String line = null;
- try
- {
- line = classList.readLine();
- }
- catch (IOException iox)
- {
- System.err.println("Error reading Classlist");
- System.exit(1);
+ try {
+ try {
+ classList = new BufferedReader(new FileReader(td));
+ } catch (FileNotFoundException e) {
+ throw new Error("TESTBUG: Error finding Classlist", e);
}
- try
- {
- maxClassIndex = Math.abs(Integer.parseInt(line));//ClassArray.length;
+ String line = null;
+ try {
+ line = classList.readLine();
+ } catch (IOException e) {
+ throw new Error("TESTBUG: Error reading Classlist", e);
}
- catch (NumberFormatException nfx)
- {
- System.err.println("Error reading Classlist - first number must be number of methods defined");
- System.exit(1);
+
+ try {
+ // ClassArray.length;
+ maxClassIndex = Math.abs(Integer.parseInt(line));
+ } catch (NumberFormatException e) {
+ throw new Error("TESTBUG: Error reading Classlist - first number must be number of methods defined", e);
}
- ClassArray = new String [maxClassIndex];
-ClassInstanceArray = new Class [maxClassIndex];
- MethodName_Array = new String [maxClassIndex];
- MethodInstance_Array = new Method [maxClassIndex];
- MethodID_Array = new int [maxClassIndex];
+ ClassArray = new String[maxClassIndex];
+ ClassInstanceArray = new Class[maxClassIndex];
+ MethodName_Array = new String[maxClassIndex];
+ MethodInstance_Array = new Method[maxClassIndex];
+ MethodID_Array = new int[maxClassIndex];
- int i;
- for (i = 0; (i<maxClassIndex) && (line != null); i++)
- {
- try
- {
- line = classList.readLine();
- }
- catch (IOException iox)
- {
- System.err.println("Error reading ClasslistFile: testListPath");
- System.exit(1);
- }
+ int i;
+ for (i = 0; i < maxClassIndex; i++) {
+ try {
+ line = classList.readLine();
+ } catch (IOException e) {
+ throw new Error("TESTBUG: Error reading ClasslistFile: testListPath", e);
+ }
StringTokenizer lineTokens = new StringTokenizer(line, "\t ");
- if (lineTokens.countTokens() <3)
- {
- System.out.println("Error reading ClasslistFile: Errored line");
- i--;
- }
- else
- {
+ if (lineTokens.countTokens() < 3) {
+ throw new Error("TESTBUG: ClasslistFile: unexpected line:" + line);
+ } else {
ClassArray[i] = lineTokens.nextToken();
- MethodName_Array[i] =lineTokens.nextToken();
+ MethodName_Array[i] = lineTokens.nextToken();
MethodID_Array[i] = Integer.parseInt(lineTokens.nextToken());
- }
+ }
}
- maxClassIndex = i;
+ maxClassIndex = i;
+ } finally {
+ if (classList != null) {
+ try {
+ classList.close();
+ } catch (IOException e) {
+ throw new Error("can't close file", e);
+ }
+ }
+ }
- indexGenerator = new Random(RANDOM_SEED);
- if ((NUM_TEST_CLASSES < ClassArray.length) && (NUM_TEST_CLASSES > 0))
- maxClassIndex = NUM_TEST_CLASSES;
- else
- NUM_TEST_CLASSES = maxClassIndex;
+ if ((NUM_TEST_CLASSES < ClassArray.length) && (NUM_TEST_CLASSES > 0)) {
+ maxClassIndex = NUM_TEST_CLASSES;
+ } else {
+ NUM_TEST_CLASSES = maxClassIndex;
+ }
}
- //does a binary serach to find the index for the ID of a method
- private static int ID_BinSearch(int begin, int end, int ID)
- {
- if (end < begin)
- return(-1);
+ // does a binary search to find the index for the ID of a method
+ private static int ID_BinSearch(int begin, int end, int ID) {
+ if (end < begin) {
+ return (-1);
+ }
- int mid = (begin + end)/2;
+ int mid = (begin + end) / 2;
int midvalue = MethodID_Array[mid];
- if (ID == midvalue)
+ if (ID == midvalue) {
return (mid);
- else if (ID < midvalue)
- return(ID_BinSearch(begin, mid-1, ID));
- else
- return(ID_BinSearch(mid+1, end, ID));
+ } else if (ID < midvalue) {
+ return (ID_BinSearch(begin, mid - 1, ID));
+ } else {
+ return (ID_BinSearch(mid + 1, end, ID));
+ }
}
- //based off a static index, this function selects the method to be called
- public static MethodData returnNextStaticMethod(int Method_ID)
- {
- //int i = ID_BinSearch(0, MethodID_Array.length - 1, Method_ID);
- int i = ID_BinSearch(0, maxClassIndex - 1, Method_ID);
+ // based off a static index, this function selects the method to be called
+ public static MethodData returnNextStaticMethod(int Method_ID) {
+ //int i = ID_BinSearch(0, MethodID_Array.length - 1, Method_ID);
+ int i = ID_BinSearch(0, maxClassIndex - 1, Method_ID);
- return(nextStaticMethod((i==-1)?0:i));
+ return (nextStaticMethod((i == -1) ? 0 : i));
}
- //this function randomly selects the next method to be called by the test class
- public static MethodData nextRandomMethod()
- {
-
+ // this function randomly selects the next method to be called by the test class
+ public static MethodData nextRandomMethod() {
int i = indexGenerator.nextInt(maxClassIndex);
- return(nextStaticMethod(i));
+ return (nextStaticMethod(i));
}
- private static MethodData nextStaticMethod(int i)
- {
+ private static MethodData nextStaticMethod(int i) {
Class methodsClass = null;
Method nextMethod = null;
- try
- {
- //methodsClass = CGTTestLoader.findClass(ClassArray[i]);
- methodsClass = ClassInstanceArray[i];
- if (methodsClass == null)
- {
- methodsClass = Class.forName(ClassArray[i]);
- ClassInstanceArray[i] = methodsClass;
- }
- nextMethod = MethodInstance_Array[i];
- if (nextMethod == null )
- {
- nextMethod =
- methodsClass.getMethod(MethodName_Array[i],
- new Class[]{java.util.Vector.class, java.util.Vector.class,
- java.lang.Long.class, java.lang.Integer.class});
- //sum vector, ID vector, function depth, static function call depth
- MethodInstance_Array[i] = nextMethod;
- }
+ try {
+ methodsClass = ClassInstanceArray[i];
+ if (methodsClass == null) {
+ methodsClass = Class.forName(ClassArray[i]);
+ ClassInstanceArray[i] = methodsClass;
}
- catch (ClassNotFoundException cnfx)
- {
- System.out.println("Class: " +ClassArray[i]+ " Not Found");
- System.exit(-1);
+ nextMethod = MethodInstance_Array[i];
+ if (nextMethod == null) {
+ nextMethod = methodsClass.getMethod(MethodName_Array[i],
+ Vector.class, Vector.class, Long.class, Integer.class);
+ // sum vector, ID vector, function depth, static function call depth
+ MethodInstance_Array[i] = nextMethod;
}
- catch (NoSuchMethodException nsmx)
- {
- System.out.println("Class: " +ClassArray[i]);
- System.out.println("Method: " +MethodName_Array[i]+" Not Found");
- System.exit(-1);
- }
- catch (SecurityException sx)
- {
- System.out.println("Class: " +ClassArray[i]);
- System.out.println("Method: " +MethodName_Array[i]);
- System.out.println("Security Exception Generated, by above method call");
- System.exit(-1);
- }
- return(new MethodData(ClassArray[i], MethodName_Array[i], methodsClass, nextMethod, MethodID_Array[i]));
+ } catch (ClassNotFoundException e) {
+ throw new Error("TESTBUG Class: " + ClassArray[i] + " Not Found", e);
+ } catch (NoSuchMethodException e) {
+ throw new Error("TESTBUG Method: " + ClassArray[i] + "::" + MethodName_Array[i] + " Not Found", e);
+ } catch (SecurityException e) {
+ throw new Error("TESTBUG Security Exception Generated by " + ClassArray[i] + "::" + MethodName_Array[i], e);
+ }
+ return new MethodData(ClassArray[i], MethodName_Array[i], methodsClass, nextMethod, MethodID_Array[i]);
}
- /*These two functions are used to verify that all function were called in the proper order*/
+ /* These two functions are used to verify that all function were called in the proper order */
- //called by "parent" function to add childs ID to vector
- public static void addFunctionIDToVector(int FunctionIndex, Vector IDVector)
- {
- IDVector.addElement(new Integer(FunctionIndex));
+ // called by "parent" function to add childs ID to vector
+ public static void addFunctionIDToVector(int FunctionIndex, Vector IDVector) {
+ IDVector.addElement(FunctionIndex);
}
- //called by "child" to add Function Index to Vector
- public static void appendSumToSumationVector(int FunctionIndex, Vector SummationVector)
- {
- if (SummationVector.isEmpty())
- SummationVector.addElement(new Long(FunctionIndex));
- else
- SummationVector.addElement(new Long(((Long)SummationVector.lastElement()).longValue() + FunctionIndex));
+ // called by "child" to add Function Index to Vector
+ public static void appendSumToSummationVector(int FunctionIndex, Vector SummationVector) {
+ if (SummationVector.isEmpty()) {
+ SummationVector.addElement((long) FunctionIndex);
+ } else {
+ SummationVector.addElement((Long) SummationVector.lastElement() + FunctionIndex);
+ }
}
- //This function calls a method based off of MethodData
+ // This function calls a method based off of MethodData
public static void callMethod(MethodData methodCallStr,
Vector summation, Vector ID,
Long numFcalls, Integer staticFcalls)
- throws InvocationTargetException
-
- {
- if(NUM_THREADS >1)
- {
- if ((staticFcalls.intValue() + numFcalls.longValue()) %23 == 0)
- {
- try
- {
- Thread.sleep(225);
- }
- catch (InterruptedException ie)
- {}
- if (VERBOSE)
- System.out.println("\t\tCurrentThread:" + Thread.currentThread().getName());
- }
- }
-
- try
- {
- methodCallStr.nextMethod.invoke(methodCallStr.instance,
- new Object []{summation, ID, numFcalls, staticFcalls});
- }
- catch (IllegalAccessException iax) //should never happen with a valid testfile
- {
- throw new TestFailure("Illegal Access Exception");
- }
- /*
- catch (InvocationTargetException itx)
- {
- itx.printStackTrace();
- System.out.println("Invocation Target Exception");
- System.exit(1);
- }*/
+ throws InvocationTargetException {
+ try {
+ methodCallStr.nextMethod.invoke(methodCallStr.instance,
+ summation, ID, numFcalls, staticFcalls);
+ } catch (IllegalAccessException e) {
+ // should never happen with a valid testfile
+ throw new TestFailure("Illegal Access Exception", e);
+ }
}
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/MethodData.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/MethodData.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,37 +20,33 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import java.lang.reflect.*;
+
+import java.lang.reflect.Method;
+
import nsk.share.TestFailure;
-public final class MethodData
-{
- public String ClassName;
- public String MethodName;
- public Class ClassObject;
- public Method nextMethod;
- public int id;
- public Object instance = null;
+public final class MethodData {
+ public String ClassName;
+ public String MethodName;
+ public Class ClassObject;
+ public Method nextMethod;
+ public int id;
+ public Object instance;
- MethodData(String ClassName, String MethodName, Class ClassObject,Method nextMethod, int id)
- {
- this.ClassName = ClassName;
- this.MethodName = MethodName;
- this.nextMethod = nextMethod;
- this.id = id;
- this.ClassObject = ClassObject;
- try
- {
- this.instance = ClassObject.newInstance();
- }
- catch (InstantiationException ix)
- {
- throw new TestFailure("Class: " +ClassName+ " Instantiation Exception");
- }
- catch (IllegalAccessException iax)
- {
- throw new TestFailure("Class: " +ClassName+ " Illegal Access Exception");
- }
- }
+ MethodData(String ClassName, String MethodName, Class ClassObject, Method nextMethod, int id) {
+ this.ClassName = ClassName;
+ this.MethodName = MethodName;
+ this.nextMethod = nextMethod;
+ this.id = id;
+ this.ClassObject = ClassObject;
+ try {
+ this.instance = ClassObject.newInstance();
+ } catch (InstantiationException e) {
+ throw new TestFailure("Class: " + ClassName + " Instantiation Exception", e);
+ } catch (IllegalAccessException e) {
+ throw new TestFailure("Class: " + ClassName + " Illegal Access Exception", e);
+ }
+ }
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/Node.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/Node.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,114 +20,102 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import nsk.share.TestFailure;
// This class define the tree node.
-public class Node
-{
- public final static int Black = 0; // constants used to define the
- public final static int Red = 1; // node color
- public final static int Left_son = 2; // constants used to identify
- public final static int Right_son = 3;// the node parent and sons.
- public final static int Parent = 4;
+public class Node {
+ public final static int Black = 0; // constants used to define the
+ public final static int Red = 1; // node color
+ public final static int Left_son = 2; // constants used to identify
+ public final static int Right_son = 3;// the node parent and sons.
+ public final static int Parent = 4;
-
- private int color;
- private int key;
- private Node L,R,P; // L-left son,R-right son,P-parent
+ private int color;
+ private int key;
+ private Node L, R, P; // L-left son,R-right son,P-parent
- // constructor create a new node the default color is red
- // the default appearance (bold) is regular.
- // initialize the key field.
+ // constructor create a new node the default color is red
+ // the default appearance (bold) is regular.
+ // initialize the key field.
- public Node(int k)
- {
- color = Red;
- key = k;
- L = null;
- R = null;
- P = null;
- }
+ public Node(int k) {
+ color = Red;
+ key = k;
+ L = null;
+ R = null;
+ P = null;
+ }
- // constructor for constructing a tree null object, is color
- // is black.
+ // constructor for constructing a tree null object, is color
+ // is black.
- public Node()
- {
- color = Black;
- key = -1;
- L = null;
- R = null;
- P = null;
- }
+ public Node() {
+ color = Black;
+ key = -1;
+ L = null;
+ R = null;
+ P = null;
+ }
- // This method set the node key.
+ // This method set the node key.
- public void setKey(int k)
- {
- key = k;
- }
+ public void setKey(int k) {
+ key = k;
+ }
- // This method return the node key.
+ // This method return the node key.
- public int getKey()
- {
- return (key);
- }
+ public int getKey() {
+ return (key);
+ }
- // This method set the node color.
+ // This method set the node color.
- public void setColor(int c)
- {
- if (c == Black)
- color = Black;
- else
- if (c == Red)
+ public void setColor(int c) {
+ if (c == Black) {
+ color = Black;
+ } else if (c == Red) {
color = Red;
- }
+ }
+ }
- // This method return the node color.
+ // This method return the node color.
- public int getColor()
- {
- return (color);
- }
+ public int getColor() {
+ return (color);
+ }
- // This method set the node parent or childs acording to the who
- // parameter.
+ // This method set the node parent or childs acording to the who
+ // parameter.
- public void setNode(int who,Node n)
- {
- switch (who)
- {
- case Left_son:
- L = n;
- break;
- case Right_son:
- R = n;
- break;
- case Parent:
- P = n;
- break;
- }
- }
+ public void setNode(int who, Node n) {
+ switch (who) {
+ case Left_son:
+ L = n;
+ break;
+ case Right_son:
+ R = n;
+ break;
+ case Parent:
+ P = n;
+ break;
+ }
+ }
- // This method return the node parent or childs acording to the who
- // parameter.
+ // This method return the node parent or childs acording to the who
+ // parameter.
- public Node getNode(int who)
- {
- switch (who)
- {
- case Left_son:
- return (L);
- case Right_son:
- return (R);
- case Parent:
- return (P);
- }
- return (null);
- }
+ public Node getNode(int who) {
+ switch (who) {
+ case Left_son:
+ return L;
+ case Right_son:
+ return R;
+ case Parent:
+ return P;
+ }
+ return null;
+ }
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/RBTree.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/RBTree.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,708 +20,626 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import nsk.share.TestFailure;
-
-//import Node;
-
// This class defines the tree object.
-
-public class RBTree
-{
- public final static int maxNodes = 70; // maximum nodes allowed.
- public final static int INSERT = 0; // constants indicating
- public final static int DELETE = 1; // the current operation
- public final static int NOP = 2;
- public final static Node treeNull = new Node(); // the tree NULL node.
+public class RBTree {
+ public final static int maxNodes = 70; // maximum nodes allowed.
+ public final static int INSERT = 0; // constants indicating
+ public final static int DELETE = 1; // the current operation
+ public final static int NOP = 2;
+ public final static Node treeNull = new Node(); // the tree NULL node.
- private Node root;
- private int num_of_nodes;
- private int height; // The tree heigth ,it is updated
- // in each operation.
+ private Node root;
+ private int num_of_nodes;
+ private int height; // The tree height, it is updated
+ // in each operation.
- // since the algorithem is executed in stages I have to remember data
- // on the state.
- private Node node; // The current operation is being done on it.
- private int action;// The operation being performed (insert / delete)
- private int stage; // The current stage of execution
-
- // the constructor initialize the object fields.
+ // since the algorithm is executed in stages I have to remember data
+ // on the state.
+ private Node node; // The current operation is being done on it.
+ private int action; // The operation being performed (insert / delete)
+ private int stage; // The current stage of execution
- public RBTree()
- {
- root = treeNull;
- node = treeNull;
- num_of_nodes = 0;
- height = 0;
- action = NOP;
- stage = 0;
- }
-
- // This method return the root of the tree.
+ // the constructor initializes the object fields.
+ public RBTree() {
+ root = treeNull;
+ node = treeNull;
+ num_of_nodes = 0;
+ height = 0;
+ action = NOP;
+ stage = 0;
+ }
- public Node getRoot()
- {
- return root;
- }
-
- // This method return the number of nodes in the tree.
+ // This method returns the root of the tree.
+ public Node getRoot() {
+ return root;
+ }
- public int getNodes()
- {
- return num_of_nodes;
- }
+ // This method returns the number of nodes in the tree.
+ public int getNodes() {
+ return num_of_nodes;
+ }
- // This method return the heigth of the tree.
-
- public int getHeight()
- {
- return height;
- }
+ // This method returns the height of the tree.
+ public int getHeight() {
+ return height;
+ }
-
- // This method inserts k into the Red Black Tree
+ // This method inserts k into the Red Black Tree
+ public boolean RBInsert(int k) {
+ // checking similar to the RB_Insert method
+ if (action != NOP) {
+ System.out.println("Only one operation can be done at a time.");
+ return false;
+ }
- public boolean RBInsert(int k)
- {
+ if (num_of_nodes == maxNodes) {
+ System.out.println("The maximum nodes allowed is already reached.");
+ return false;
+ }
- Thread Pause = new Thread(); // this thread is used for delay
- // between the stages.
- if (action != NOP) // checking similar to the RB_Insert method
- {
- System.out.println
- ("Only one operation can be done at a time.");
- return false;
- }
- if (num_of_nodes == maxNodes)
- {
- System.out.println
- ("The maximum nodes allowed is already reached.");
- return false;
- }
- if (Search(k) == treeNull) // Check if there is already node with key k.
- {
- action = INSERT;
- node = new Node(k);
- node.setNode(Node.Left_son,treeNull);
- node.setNode(Node.Right_son,treeNull);
- node.setNode(Node.Parent,treeNull);
- stage = 1;
- while (stage != 0) // This is the loop that perform all the
- { // operation steps.
- InsertStep(); // perform one step
- updateHeight(); // update the tree height
- }
- action = NOP; // set the action to NoOPretion.
- return true;
- }
- else
- System.out.println
- ("Insertion failed. This key already exist.");
- return false;
- }
+ // Check if there is already node with key k.
+ if (Search(k) == treeNull) {
+ action = INSERT;
+ node = new Node(k);
+ node.setNode(Node.Left_son, treeNull);
+ node.setNode(Node.Right_son, treeNull);
+ node.setNode(Node.Parent, treeNull);
+ stage = 1;
+ // This is the loop that perform all the operation steps.
+ while (stage != 0) {
+ // perform one step
+ InsertStep();
+ // update the tree height
+ updateHeight();
+ }
+ // set the action to NoOPretion.
+ action = NOP;
+ return true;
+ } else
+ System.out.println("Insertion failed. This key already exist.");
+ return false;
+ }
- // This method deletes the element k from the Red Black tree
-
- public boolean RBDelete(int k)
- {
- Thread Pause = new Thread(); // this thread is used for delay
- // between the stages.
- if (action != NOP)
- { // checking like in RB_Delete method
- System.out.println
- ("Only one operation can be done at a time.");
- return false;
- }
- node = Search(k);
- if (node != treeNull) // Check if there is a node with key k.
- {
- action = DELETE;
- stage = 1;
- while (stage != 0) // this loop perform all the operation
- { // steps.
- DeleteStep(); // perform one step
- updateHeight(); // update the tree height
-
- }
- action = NOP;
- return true;
- }
- else
- System.out.println
- ("Deletion failed. This key doesn't exist.");
- return false;
- }
+ // This method deletes the element k from the Red Black tree
+ public boolean RBDelete(int k) {
+ // checking like in RB_Delete method
+ if (action != NOP) {
+ System.out.println("Only one operation can be done at a time.");
+ return false;
+ }
+ node = Search(k);
+ // Check if there is a node with key k.
+ if (node != treeNull) {
+ action = DELETE;
+ stage = 1;
+ // this loop perform all the operation steps.
+ while (stage != 0) {
+ // perform one step
+ DeleteStep();
+ // update the tree height
+ updateHeight();
+ }
+ action = NOP;
+ return true;
+ } else
+ System.out.println("Deletion failed. This key doesn't exist.");
+ return false;
+ }
- // This method perform one step in the insertion operation.
- // If perform a step acording to the stage variable.
- // I will not explain exactly what each stage do, just that they
- // divided to 4 categories:
- // 1. inserting a node to the tree.
- // 2. marking nodes that will be recolored.
- // 3. recoloring nodes.
- // 4. rotating right or left.
-
- private void InsertStep()
- {
- Node Pr,GrPr,Un; // Pr is parent, GrPr is grandparent
- // and Un is uncle.
- switch (stage)
- {
- case 1: // Inserting a node to the tree
- /*
- System.out.println // send a message to the screen
- (new String("Inserting ")
- .concat(Integer.toString(node.getKey())));
- */
- Tree_Insert(); // inserting an element to the tree
- break;
- case 2: // mid stage that move to algorithem to the
- // proper next stage, and send proper message
- // to the screen
- Pr = node.getNode(Node.Parent);
- GrPr = Pr.getNode(Node.Parent);
- if (Pr == GrPr.getNode(Node.Left_son))
- {
- Un = GrPr.getNode(Node.Right_son);
- if (Un.getColor() == Node.Red)
- {
+ // This method performs one step in the insertion operation.
+ // It performs a step according to the stage variable.
+ // I will not explain exactly what each stage do, just that they
+ // divided to 4 categories:
+ // 1. inserting a node to the tree.
+ // 2. marking nodes that will be recolored.
+ // 3. recoloring nodes.
+ // 4. rotating right or left.
+ private void InsertStep() {
+ // Pr is parent, GrPr is grandparent and Un is uncle.
+ Node Pr, GrPr, Un;
+ switch (stage) {
+ // Inserting a node to the tree
+ case 1:
+ Tree_Insert();
+ break;
+ // mid stage that moves the algorithm to the proper next stage
+ case 2:
+ Pr = node.getNode(Node.Parent);
+ GrPr = Pr.getNode(Node.Parent);
+ if (Pr == GrPr.getNode(Node.Left_son)) {
+ Un = GrPr.getNode(Node.Right_son);
+ if (Un.getColor() == Node.Red) {
+ stage = 3;
+ } else if (node == Pr.getNode(Node.Right_son)) {
+ node = Pr;
+ stage = 5;
+ } else {
+ stage = 6;
+ }
+ } else {
+ Un = GrPr.getNode(Node.Left_son);
+ if (Un.getColor() == Node.Red) {
stage = 3;
- }
- else
- if (node == Pr.getNode(Node.Right_son))
- {
- node = Pr;
- stage = 5;
- }
- else
- {
- stage = 6;
- }
- }
- else
- {
- Un = GrPr.getNode(Node.Left_son);
- if (Un.getColor() == Node.Red)
- {
- stage = 3;
- }
- else
- if (node == Pr.getNode(Node.Left_son))
- {
- node = Pr;
- stage = 5;
- }
- else
- {
- stage = 6;
- }
- }
- break;
- case 3: // This stage marks node that will be recolored
- Pr = node.getNode(Node.Parent);
- GrPr = Pr.getNode(Node.Parent);
- if (Pr == GrPr.getNode(Node.Left_son))
- Un = GrPr.getNode(Node.Right_son);
- else
- Un = GrPr.getNode(Node.Left_son);
+ } else if (node == Pr.getNode(Node.Left_son)) {
+ node = Pr;
+ stage = 5;
+ } else {
+ stage = 6;
+ }
+ }
+ break;
+ // This stage marks node that will be recolored
+ case 3:
+ Pr = node.getNode(Node.Parent);
+ GrPr = Pr.getNode(Node.Parent);
+ if (Pr == GrPr.getNode(Node.Left_son)) {
+ Un = GrPr.getNode(Node.Right_son);
+ } else {
+ Un = GrPr.getNode(Node.Left_son);
+ }
+ node = GrPr;
+ stage = 4;
+ break;
+ // This stage recolors marked nodes.
+ case 4:
+ node.setColor(Node.Red);
+ node.getNode(Node.Left_son).setColor(Node.Black);
+ node.getNode(Node.Right_son).setColor(Node.Black);
- node = GrPr;
- stage = 4;
- break;
- case 4: // this stage recolor marked nodes.
- node.setColor(Node.Red);
- (node.getNode(Node.Left_son)).setColor(Node.Black);
- (node.getNode(Node.Right_son)).setColor(Node.Black);
-
- if ((node == root) ||
- ((node.getNode(Node.Parent)).getColor() == Node.Black))
- if (root.getColor() == Node.Red)
- {
+ if ((node == root) ||
+ (node.getNode(Node.Parent).getColor() == Node.Black)) {
+ if (root.getColor() == Node.Red) {
stage = 9;
- }
- else
+ } else
stage = 0;
- else
- {
- stage = 2;
- InsertStep();
- }
- break;
- case 5: // This stage perform rotation operation
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- Left_Rotate(node);
- else
- Right_Rotate(node);
+ } else {
+ stage = 2;
+ InsertStep();
+ }
+ break;
+ // This stage performs rotation operation
+ case 5:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Left_Rotate(node);
+ } else {
+ Right_Rotate(node);
+ }
+ stage = 6;
+ break;
+ // This stage marks nodes that will be recolor.
+ case 6:
+ Pr = node.getNode(Node.Parent);
+ GrPr = Pr.getNode(Node.Parent);
- stage = 6;
- break;
- case 6: // This stage marks nodes that will be recolor.
- Pr = node.getNode(Node.Parent);
- GrPr = Pr.getNode(Node.Parent);
-
- stage = 7;
- break;
- case 7: // This stage recolor marked nodes.
- Pr = node.getNode(Node.Parent);
- Pr.setColor(Node.Black);
- GrPr = Pr.getNode(Node.Parent);
- GrPr.setColor(Node.Red);
+ stage = 7;
+ break;
+ // This stage recolors marked nodes.
+ case 7:
+ Pr = node.getNode(Node.Parent);
+ Pr.setColor(Node.Black);
+ GrPr = Pr.getNode(Node.Parent);
+ GrPr.setColor(Node.Red);
- stage = 8;
- break;
- case 8: // This stage perform rotation operation
- Pr = node.getNode(Node.Parent);
- GrPr = Pr.getNode(Node.Parent);
- if (Pr == GrPr.getNode(Node.Left_son))
- Right_Rotate(GrPr);
- else
- Left_Rotate(GrPr);
- if (root.getColor() == Node.Red)
- {
- stage = 9;
- }
- else
- stage = 0;
- break;
- case 9: // this stage mark the root.
- stage = 10;
- break;
- case 10: // This stage recolor the root.
- root.setColor(Node.Black);
- stage = 0;
- break;
- }
- }
+ stage = 8;
+ break;
+ // This stage performs rotation operation
+ case 8:
+ Pr = node.getNode(Node.Parent);
+ GrPr = Pr.getNode(Node.Parent);
+ if (Pr == GrPr.getNode(Node.Left_son)) {
+ Right_Rotate(GrPr);
+ } else {
+ Left_Rotate(GrPr);
+ }
+ if (root.getColor() == Node.Red) {
+ stage = 9;
+ } else
+ stage = 0;
+ break;
+ // this stage marks the root.
+ case 9:
+ stage = 10;
+ break;
+ // This stage recolors the root.
+ case 10:
+ root.setColor(Node.Black);
+ stage = 0;
+ break;
+ }
+ }
- // This method perform one step in the deletion operation.
- // If perform a step acording to the stage variable.
- // I will explain exactly what each stage do, just that they
- // divided to 4 categories:
- // 1. deleting a node from the tree.
- // 2. marking nodes that will be recolored.
- // 3. recoloring nodes.
- // 4. rotating right or left.
+ // This method performs one step in the deletion operation.
+ // It perform sa step according to the stage variable.
+ // I will explain exactly what each stage do, just that they
+ // divided to 4 categories:
+ // 1. deleting a node from the tree.
+ // 2. marking nodes that will be recolored.
+ // 3. recoloring nodes.
+ // 4. rotating right or left.
+ public void DeleteStep() {
+ // Pr is Parent, Br is Brother
+ Node Pr, Br;
+ switch (stage) {
+ // This stage delete a node from the tree.
+ case 1:
+ Tree_Delete();
+ break;
+ // This stage marks a nodes that will be recolored or perform other stage.
+ case 2:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ }
+ if (Br.getColor() == Node.Red) {
+ stage = 3;
+ } else if ((Br.getNode(Node.Right_son).getColor() == Node.Black)
+ && (Br.getNode(Node.Left_son).getColor() == Node.Black)) {
+ stage = 5;
+ DeleteStep();
+ } else {
+ stage = 7;
+ DeleteStep();
+ }
+ break;
+ // This stage recolors marked nodes.
+ case 3:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ }
+ Br.setColor(Node.Black);
+ Pr.setColor(Node.Red);
- public void DeleteStep()
- {
- Node Pr,Br; // Pr is Parent ,Br is Brother
- switch (stage)
- {
- case 1: // This stage delete a node from the tree.
- /*
- System.out.println
- (new String("Deleting ")
- .concat(Integer.toString(node.getKey())));
- */
- Tree_Delete();
- break;
- case 2: // This stage marks a nodes that will be recolored
- // or perform other stage.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- Br = Pr.getNode(Node.Right_son);
- else
- Br = Pr.getNode(Node.Left_son);
- if (Br.getColor() == Node.Red)
- {
- stage = 3;
+ stage = 4;
+ break;
+ // This stage performs rotation operation
+ case 4:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Left_Rotate(Pr);
+ Br = Pr.getNode(Node.Right_son);
+ } else {
+ Right_Rotate(Pr);
+ Br = Pr.getNode(Node.Left_son);
+ }
+ if ((Br.getNode(Node.Right_son).getColor() == Node.Black)
+ && (Br.getNode(Node.Left_son).getColor() == Node.Black)) {
+ stage = 5;
+ } else {
+ stage = 7;
+ }
+
+ break;
+ // This stage marks nodes that will be recolor.
+ case 5:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ }
+ stage = 6;
+ break;
+ // This stage recolors marked nodes.
+ case 6:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ }
+ Br.setColor(Node.Red);
+ node = Pr;
+
+ if ((node != root) && (node.getColor() == Node.Black)) {
+ stage = 2;
+ } else if (node.getColor() == Node.Red) {
+ stage = 13;
+ } else
+ stage = 0;
+ break;
+ // This stage marks nodes that will be recolor or perform other stage.
+ case 7:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ if ((Br.getNode(Node.Right_son)).getColor() == Node.Black) {
+ stage = 8;
+ } else {
+ stage = 10;
+ DeleteStep();
}
- else
- if (((Br.getNode(Node.Right_son)).getColor() == Node.Black)
- && ((Br.getNode(Node.Left_son)).getColor() == Node.Black))
- {
- stage = 5;
- DeleteStep();
- }
- else
- {
- stage = 7;
- DeleteStep();
- }
- break;
- case 3: // this stage recolor marked nodes.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Br = Pr.getNode(Node.Right_son);
-
- }
- else
- {
- Br = Pr.getNode(Node.Left_son);
- }
- Br.setColor(Node.Black);
- Pr.setColor(Node.Red);
-
- stage = 4;
- break;
- case 4: // this stage perform rotation operation
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Left_Rotate(Pr);
- Br = Pr.getNode(Node.Right_son);
- }
- else
- {
- Right_Rotate(Pr);
- Br = Pr.getNode(Node.Left_son);
- }
- if (((Br.getNode(Node.Right_son)).getColor() == Node.Black)
- && ((Br.getNode(Node.Left_son)).getColor() == Node.Black))
- stage = 5;
- else
- stage = 7;
-
- break;
- case 5: // this stage marks nodes that will be recolor.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- Br = Pr.getNode(Node.Right_son);
- else
- Br = Pr.getNode(Node.Left_son);
-
- stage = 6;
- break;
- case 6: // This stage recolor marked nodes.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- Br = Pr.getNode(Node.Right_son);
- else
- Br = Pr.getNode(Node.Left_son);
- Br.setColor(Node.Red);
- node = Pr;
-
- if ((node != root) && (node.getColor() == Node.Black))
- stage = 2;
- else
- if (node.getColor() == Node.Red)
- {
- stage = 13;
- }
- else
- stage = 0;
- break;
- case 7: // this stage marks nodes that will be recolor
- // or perform other stage.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Br = Pr.getNode(Node.Right_son);
- if ((Br.getNode(Node.Right_son)).getColor() == Node.Black)
- {
- stage = 8;
- }
- else
- {
- stage = 10;
- DeleteStep();
- }
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ if ((Br.getNode(Node.Left_son)).getColor() == Node.Black) {
+ stage = 8;
+ } else {
+ stage = 10;
+ DeleteStep();
}
- else
- {
- Br = Pr.getNode(Node.Left_son);
- if ((Br.getNode(Node.Left_son)).getColor() == Node.Black)
- {
- stage = 8;
- }
- else
- {
- stage = 10;
- DeleteStep();
- }
- }
- break;
- case 8: // this stage recolor marked nodes.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Br = Pr.getNode(Node.Right_son);
- (Br.getNode(Node.Left_son)).setColor(Node.Black);
-
- }
- else
- {
- Br = Pr.getNode(Node.Left_son);
- (Br.getNode(Node.Right_son)).setColor(Node.Black);
+ }
+ break;
+ // This stage recolors marked nodes.
+ case 8:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ Br.getNode(Node.Left_son).setColor(Node.Black);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ Br.getNode(Node.Right_son).setColor(Node.Black);
+ }
+ Br.setColor(Node.Red);
+ stage = 9;
+ break;
+ // This stage performs rotation operation
+ case 9:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ Right_Rotate(Br);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ Left_Rotate(Br);
+ }
- }
- Br.setColor(Node.Red);
- stage = 9;
- break;
- case 9: // this stage perform rotation operation
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Br = Pr.getNode(Node.Right_son);
- Right_Rotate(Br);
- }
- else
- {
- Br = Pr.getNode(Node.Left_son);
- Left_Rotate(Br);
- }
-
- stage = 10;
- break;
- case 10: // This stage marks node that will be recolor.
+ stage = 10;
+ break;
+ // This stage marks node that will be recolor.
+ case 10:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ }
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Br = Pr.getNode(Node.Right_son);
- }
- else
- {
- Br = Pr.getNode(Node.Left_son);
- }
+ stage = 11;
+ break;
+ // This stage recolors marked nodes.
+ case 11:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Br = Pr.getNode(Node.Right_son);
+ Br.getNode(Node.Right_son).setColor(Node.Black);
+ } else {
+ Br = Pr.getNode(Node.Left_son);
+ Br.getNode(Node.Left_son).setColor(Node.Black);
- stage = 11;
- break;
- case 11: // this stage recolor marked nodes.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- {
- Br = Pr.getNode(Node.Right_son);
- (Br.getNode(Node.Right_son)).setColor(Node.Black);
- }
- else
- {
- Br = Pr.getNode(Node.Left_son);
- (Br.getNode(Node.Left_son)).setColor(Node.Black);
+ }
+ if (Br.getColor() != Pr.getColor()) {
+ Br.setColor(Pr.getColor());
+ }
+ if (Pr.getColor() != Node.Black) {
+ Pr.setColor(Node.Black);
+ }
- }
- if (Br.getColor() != Pr.getColor())
- Br.setColor(Pr.getColor());
- if (Pr.getColor() != Node.Black)
- Pr.setColor(Node.Black);
-
- stage = 12;
- break;
- case 12: // this stage perform rotation operation.
- Pr = node.getNode(Node.Parent);
- if (node == Pr.getNode(Node.Left_son))
- Left_Rotate(Pr);
- else
- Right_Rotate(Pr);
- node = root;
- if (node.getColor() == Node.Red)
- {
- stage = 13;
- }
- else
- stage = 0;
- break;
- case 13: // this stage marks a node that will be recolor
- stage = 14;
- break;
- case 14: // this stage recolor marked node.
- node.setColor(Node.Black);
+ stage = 12;
+ break;
+ // This stage performs rotation operation.
+ case 12:
+ Pr = node.getNode(Node.Parent);
+ if (node == Pr.getNode(Node.Left_son)) {
+ Left_Rotate(Pr);
+ } else {
+ Right_Rotate(Pr);
+ }
+ node = root;
+ if (node.getColor() == Node.Red) {
+ stage = 13;
+ } else {
stage = 0;
- break;
- }
- }
-
- // This method insert the node 'node' to the tree.
- // it called from the first stage in the InsertStep method.
- // we 'dive' from the root to a leaf acording to the node key
- // and insert the node in the proper place.
+ }
+ break;
+ // This stage marks a node that will be recolored
+ case 13:
+ stage = 14;
+ break;
+ // This stage recolors marked node.
+ case 14:
+ node.setColor(Node.Black);
+ stage = 0;
+ break;
+ }
+ }
- private void Tree_Insert()
- {
- Node n1,n2;
- n1 = root;
- n2 = treeNull;
- while (n1 != treeNull)
- {
- n2 = n1;
- if (node.getKey() < n1.getKey())
- n1 = n1.getNode(Node.Left_son);
- else
- n1 = n1.getNode(Node.Right_son);
- }
- node.setNode(Node.Parent,n2);
- if (n2 == treeNull)
- root = node;
- else
- {
- if (node.getKey() < n2.getKey())
- n2.setNode(Node.Left_son,node);
- else
- n2.setNode(Node.Right_son,node);
- }
- //Parent.display.drawTree();
- // updating the insertion stage.
- if ((node == root) ||
- ((node.getNode(Node.Parent)).getColor() == Node.Black))
- if (root.getColor() == Node.Red)
- {
- stage = 9;
- }
- else
- stage = 0;
- else
- {
- stage = 2;
- InsertStep();
- }
- num_of_nodes++; // increasing the number of nodes
- }
+ // This method inserts the node 'node' to the tree.
+ // it called from the first stage in the InsertStep method.
+ // we 'dive' from the root to a leaf according to the node key
+ // and insert the node in the proper place.
+ private void Tree_Insert() {
+ Node n1, n2;
+ n1 = root;
+ n2 = treeNull;
+ while (n1 != treeNull) {
+ n2 = n1;
+ if (node.getKey() < n1.getKey()) {
+ n1 = n1.getNode(Node.Left_son);
+ } else {
+ n1 = n1.getNode(Node.Right_son);
+ }
+ }
+ node.setNode(Node.Parent, n2);
+ if (n2 == treeNull) {
+ root = node;
+ }
+ else {
+ if (node.getKey() < n2.getKey()) {
+ n2.setNode(Node.Left_son, node);
+ } else {
+ n2.setNode(Node.Right_son, node);
+ }
+ }
+ // updating the insertion stage.
+ if ((node == root) ||
+ (node.getNode(Node.Parent).getColor() == Node.Black)) {
+ if (root.getColor() == Node.Red) {
+ stage = 9;
+ } else {
+ stage = 0;
+ }
+ } else {
+ stage = 2;
+ InsertStep();
+ }
+ num_of_nodes++; // increasing the number of nodes
+ }
- // This method delete the node 'node' from the tree.
- // it called from the first stage in the DeleteStep method.
- // if node has at most one son we just remove it and connect
- // his son and parent. If it has 2 sons we delete his successor
- // that has at most one son and replace him with the successor.
+ // This method deletes the node 'node' from the tree.
+ // it called from the first stage in the DeleteStep method.
+ // if node has at most one son we just remove it and connect
+ // his son and parent. If it has 2 sons we delete his successor
+ // that has at most one son and replace him with the successor.
+ private void Tree_Delete() {
+ Node n1, n2, n3;
+ if ((node.getNode(Node.Left_son) == treeNull) ||
+ (node.getNode(Node.Right_son) == treeNull)) {
+ n1 = node;
+ } else {
+ n1 = Tree_Successor(node);
+ }
- private void Tree_Delete()
- {
- Node n1,n2,n3;
- if ((node.getNode(Node.Left_son) == treeNull) ||
- (node.getNode(Node.Right_son) == treeNull))
- n1 = node;
- else
- n1 = Tree_Successor(node);
- if (n1.getNode(node.Left_son) != treeNull)
- n2 = n1.getNode(Node.Left_son);
- else
- n2 = n1.getNode(Node.Right_son);
+ if (n1.getNode(Node.Left_son) != treeNull) {
+ n2 = n1.getNode(Node.Left_son);
+ } else {
+ n2 = n1.getNode(Node.Right_son);
+ }
- n3 = n1.getNode(Node.Parent);
- n2.setNode(Node.Parent,n3);
- if (n3 == treeNull)
- root = n2;
- else
- if (n1 == n3.getNode(Node.Left_son))
- n3.setNode(Node.Left_son,n2);
- else
- n3.setNode(Node.Right_son,n2);
+ n3 = n1.getNode(Node.Parent);
+ n2.setNode(Node.Parent, n3);
+ if (n3 == treeNull) {
+ root = n2;
+ } else if (n1 == n3.getNode(Node.Left_son)) {
+ n3.setNode(Node.Left_son, n2);
+ } else {
+ n3.setNode(Node.Right_son, n2);
+ }
- if (n1 != node)
- {
- node.setKey(n1.getKey());
- }
-
+ if (n1 != node) {
+ node.setKey(n1.getKey());
+ }
- node = n2;
- if (n1.getColor() == Node.Black)
- if ((node != root) && (node.getColor() == Node.Black))
- stage = 2;
- else
- if (node.getColor() == Node.Red)
- stage = 13;
- else
- stage = 0;
- else
- stage = 0;
- num_of_nodes--; // decrease the number of nodes.
- }
-
- // This method return the successor of the node n in the tree.
+ node = n2;
+ if (n1.getColor() == Node.Black) {
+ if ((node != root) && (node.getColor() == Node.Black)) {
+ stage = 2;
+ } else if (node.getColor() == Node.Red) {
+ stage = 13;
+ } else {
+ stage = 0;
+ }
+ } else {
+ stage = 0;
+ }
+ // decrease the number of nodes.
+ num_of_nodes--;
+ }
- private Node Tree_Successor(Node n)
- {
- Node n1;
- if (n.getNode(Node.Right_son) != treeNull)
- {
- n = n.getNode(Node.Right_son);
- while (n.getNode(Node.Left_son) != treeNull)
- n = n.getNode(Node.Left_son);
- return n;
- }
- n1 = n.getNode(Node.Parent);
- while ((n1 != treeNull) && (n == n1.getNode(Node.Right_son)))
- {
- n = n1;
- n1 = n1.getNode(Node.Parent);
- }
- return n1;
- }
+ // This method returns the successor of the node n in the tree.
+ private Node Tree_Successor(Node n) {
+ Node n1;
+ if (n.getNode(Node.Right_son) != treeNull) {
+ n = n.getNode(Node.Right_son);
+ while (n.getNode(Node.Left_son) != treeNull) {
+ n = n.getNode(Node.Left_son);
+ }
+ return n;
+ }
+ n1 = n.getNode(Node.Parent);
+ while ((n1 != treeNull) && (n == n1.getNode(Node.Right_son))) {
+ n = n1;
+ n1 = n1.getNode(Node.Parent);
+ }
+ return n1;
+ }
- // This method perform Left Rotation with n1.
+ // This method performs Left Rotation with n1.
+ private void Left_Rotate(Node n1) {
+ Node n2;
- private void Left_Rotate(Node n1)
- {
- Node n2;
+ n2 = n1.getNode(Node.Right_son);
+ n1.setNode(Node.Right_son, n2.getNode(Node.Left_son));
+ if (n2.getNode(Node.Left_son) != treeNull) {
+ n2.getNode(Node.Left_son).setNode(Node.Parent, n1);
+ }
+ n2.setNode(Node.Parent, n1.getNode(Node.Parent));
+ if (n1.getNode(Node.Parent) == treeNull) {
+ root = n2;
+ } else if (n1 == n1.getNode(Node.Parent).getNode(Node.Left_son)) {
+ n1.getNode(Node.Parent).setNode(Node.Left_son, n2);
+ } else {
+ n1.getNode(Node.Parent).setNode(Node.Right_son, n2);
+ }
+ n2.setNode(Node.Left_son, n1);
+ n1.setNode(Node.Parent, n2);
+ }
- n2 = n1.getNode(Node.Right_son);
- n1.setNode(Node.Right_son,n2.getNode(Node.Left_son));
- if (n2.getNode(Node.Left_son) != treeNull)
- (n2.getNode(Node.Left_son)).setNode(Node.Parent,n1);
- n2.setNode(Node.Parent,n1.getNode(Node.Parent));
- if (n1.getNode(Node.Parent) == treeNull)
- root = n2;
- else
- if (n1 == (n1.getNode(Node.Parent)).getNode(Node.Left_son))
- (n1.getNode(Node.Parent)).setNode(Node.Left_son,n2);
- else
- (n1.getNode(Node.Parent)).setNode(Node.Right_son,n2);
- n2.setNode(Node.Left_son,n1);
- n1.setNode(Node.Parent,n2);
- }
-
- // This method perform Right Rotation with n1.
-
- private void Right_Rotate(Node n1)
- {
- Node n2;
+ // This method performs Right Rotation with n1.
+ private void Right_Rotate(Node n1) {
+ Node n2;
- n2 = n1.getNode(Node.Left_son);
- n1.setNode(Node.Left_son,n2.getNode(Node.Right_son));
- if (n2.getNode(Node.Right_son) != treeNull)
- (n2.getNode(Node.Right_son)).setNode(Node.Parent,n1);
- n2.setNode(Node.Parent,n1.getNode(Node.Parent));
- if (n1.getNode(Node.Parent) == treeNull)
- root = n2;
- else
- if (n1 == (n1.getNode(Node.Parent)).getNode(Node.Left_son))
- (n1.getNode(Node.Parent)).setNode(Node.Left_son,n2);
- else
- (n1.getNode(Node.Parent)).setNode(Node.Right_son,n2);
- n2.setNode(Node.Right_son,n1);
- n1.setNode(Node.Parent,n2);
- }
-
- // This method search the tree for a node with key 'key', and
- // return the node on success otherwise treeNull.
+ n2 = n1.getNode(Node.Left_son);
+ n1.setNode(Node.Left_son, n2.getNode(Node.Right_son));
+ if (n2.getNode(Node.Right_son) != treeNull) {
+ n2.getNode(Node.Right_son).setNode(Node.Parent, n1);
+ }
+ n2.setNode(Node.Parent, n1.getNode(Node.Parent));
+ if (n1.getNode(Node.Parent) == treeNull) {
+ root = n2;
+ } else if (n1 == (n1.getNode(Node.Parent)).getNode(Node.Left_son)) {
+ n1.getNode(Node.Parent).setNode(Node.Left_son, n2);
+ } else {
+ n1.getNode(Node.Parent).setNode(Node.Right_son, n2);
+ }
+ n2.setNode(Node.Right_son, n1);
+ n1.setNode(Node.Parent, n2);
+ }
- public Node Search(int key)
- {
- Node node;
- node = root;
- while ((node != treeNull) && (key != node.getKey()))
- if (key < node.getKey())
- node = node.getNode(Node.Left_son);
- else
- node = node.getNode(Node.Right_son);
- return node;
- }
-
- // This method update the tree height it uses a recursive method
- // findheight.
+ // This method searches the tree for a node with key 'key', and
+ // returns the node on success otherwise treeNull.
+ public Node Search(int key) {
+ Node node;
+ node = root;
+ while ((node != treeNull) && (key != node.getKey())) {
+ if (key < node.getKey()) {
+ node = node.getNode(Node.Left_son);
+ } else {
+ node = node.getNode(Node.Right_son);
+ }
+ }
+ return node;
+ }
- private void updateHeight()
- {
- height = 0;
- if (root != treeNull)
- findHeight(root,1);
- }
-
- // This is a recursive method that find a node height.
+ // This method updates the tree height. it uses a recursive method
+ // findHeight.
+ private void updateHeight() {
+ height = 0;
+ if (root != treeNull) {
+ findHeight(root, 1);
+ }
+ }
- private void findHeight(Node n,int curr)
- {
- if (height < curr)
- height = curr;
- if (n.getNode(Node.Left_son) != treeNull)
- findHeight(n.getNode(Node.Left_son),curr+1);
- if (n.getNode(Node.Right_son) != treeNull)
- findHeight(n.getNode(Node.Right_son),curr+1);
- }
+ // This is a recursive method that find a node height.
+ private void findHeight(Node n, int curr) {
+ if (height < curr) {
+ height = curr;
+ }
+ if (n.getNode(Node.Left_son) != treeNull) {
+ findHeight(n.getNode(Node.Left_son), curr + 1);
+ }
+ if (n.getNode(Node.Right_son) != treeNull) {
+ findHeight(n.getNode(Node.Right_son), curr + 1);
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt0.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt0.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 1
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt0/cgt0.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt0.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 1
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt1.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt1.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 2
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt1/cgt1.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt1.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 2
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt10.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt10.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 11
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt10/cgt10.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt10.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 11
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt11.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt11.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 12
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt11/cgt11.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt11.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 12
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt2.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt2.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 3
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt2/cgt2.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt2.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 3
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt3.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt3.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 4
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt3/cgt3.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt3.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 4
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt4.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt4.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 5
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt4/cgt4.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt4.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 5
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt5.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt5.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 6
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt5/cgt5.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt5.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 6
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt6.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt6.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 7
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt6/cgt6.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt6.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 7
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt7.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt7.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 8
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt7/cgt7.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt7.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 8
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt8.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt8.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 9
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt8/cgt8.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt8.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 9
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/cgt9.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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
+ *
+ * @summary converted from VM Testbase jit/graph/cgt9.
+ * VM Testbase keywords: [jit, quick]
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller data/main.data main.data
+ * @build jit.graph.*
+ * @run main
+ * jit.graph.CGT
+ * -path main.data
+ * -numTestClass 10
+ * -randomLoop 40
+ * -staticLoop 40
+ */
+
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/cgt9/cgt9.java Wed Oct 16 01:16:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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
- * 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
- *
- * @summary converted from VM Testbase jit/graph/cgt9.
- * VM Testbase keywords: [jit, quick]
- *
- * @library /vmTestbase
- * /test/lib
- * @run driver jdk.test.lib.FileInstaller . .
- * @run driver jdk.test.lib.FileInstaller ../data/main.data main.data
- * @build jit.graph.*
- * @run driver ExecDriver --java
- * jit.graph.CGT
- * -path main.data
- * -numTestClass 10
- * -thread 1
- * -randomLoop 40
- * -staticLoop 40
- */
-
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/test1.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/test1.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,31 +20,30 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-
-
-import java.util.*;
-import java.lang.reflect.*;
import nsk.share.TestFailure;
-class test1
-{
+import java.lang.reflect.InvocationTargetException;
+import java.util.Vector;
+
+class test1 {
private final int classID = Globals.MethodID_Array[0];
public void callMe(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(classID, summation);
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(classID, summation);
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
+ }
- if (Globals.VERBOSE)
+ if (Globals.VERBOSE) {
System.out.println("test1.callMe");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
return;
}
@@ -52,16 +51,12 @@
Long numFcalls;
Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
+ if (staticFunctionDepth.intValue() > 0) {
numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(classID));
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
methodCallStr = Globals.returnNextStaticMethod(classID);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
staticFcalls = staticFunctionDepth;
methodCallStr = Globals.nextRandomMethod();
}
@@ -69,10 +64,10 @@
Globals.addFunctionIDToVector(methodCallStr.id, ID);
try {
- methodCallStr.nextMethod.invoke(methodCallStr.instance,
- new Object []{summation, ID, numFcalls, staticFcalls});
+ methodCallStr.nextMethod.invoke(methodCallStr.instance,
+ new Object[]{summation, ID, numFcalls, staticFcalls});
} catch (IllegalAccessException iax) {
- throw new TestFailure("Illegal Access Exception");
+ throw new TestFailure("Illegal Access Exception");
}
}
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/test2.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/test2.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,126 +20,98 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import java.util.*;
-import java.lang.reflect.*;
import nsk.share.TestFailure;
-class test2
-{
- private final int[] MethodID = {Globals.MethodID_Array[1],Globals.MethodID_Array[2]};
+import java.lang.reflect.InvocationTargetException;
+import java.util.Vector;
+
+class test2 {
+ private final int[] MethodID = {Globals.MethodID_Array[1], Globals.MethodID_Array[2]};
public void CallCallMe(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[1], summation);
- {
- Globals.appendSumToSumationVector(MethodID[1], summation);
-
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
+ }
- if (Globals.VERBOSE)
+ if (Globals.VERBOSE) {
System.out.println("test2.CallCallMe");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
- MethodData methodCallStr;
- Long numFcalls;
- Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[1]));
- methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
+ MethodData methodCallStr;
+ Long numFcalls;
+ Integer staticFcalls;
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue()-1);
- staticFcalls = staticFunctionDepth;
- Globals.addFunctionIDToVector(MethodID[0], ID);
- callMe(summation, ID, numFcalls, staticFcalls);
- return;
- }
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ Globals.addFunctionIDToVector(MethodID[0], ID);
+ callMe(summation, ID, numFcalls, staticFcalls);
+ return;
+ }
- try
- {
- methodCallStr.nextMethod.invoke(methodCallStr.instance,
- new Object []{summation, ID, numFcalls, staticFcalls});
- }
- catch (IllegalAccessException iax)
- {
- throw new TestFailure("Illegal Access Exception");
- }
- /*
- catch (InvocationTargetException itx)
- {
- throw itx;
- }
- */
+ try {
+ methodCallStr.nextMethod.invoke(methodCallStr.instance,
+ new Object[]{summation, ID, numFcalls, staticFcalls});
+ } catch (IllegalAccessException iax) {
+ throw new TestFailure("Illegal Access Exception");
+ }
}
public void callMe(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[0], summation);
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[0], summation);
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
+ }
- if (Globals.VERBOSE)
+ if (Globals.VERBOSE) {
System.out.println("test2.callMe");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
- MethodData methodCallStr;
- Long numFcalls;
- Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[0]));
- methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
+ MethodData methodCallStr;
+ Long numFcalls;
+ Integer staticFcalls;
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
- try
- {
- methodCallStr.nextMethod.invoke(methodCallStr.instance,
- new Object []{summation, ID, numFcalls, staticFcalls});
- }
- catch (IllegalAccessException iax)
- {
- throw new TestFailure("Illegal Access Exception");
- }
-/*
- catch (InvocationTargetException itx)
- {
- System.out.println("itx test 2");
-
- throw itx;
- }
- */
+ try {
+ methodCallStr.nextMethod.invoke(methodCallStr.instance,
+ new Object[]{summation, ID, numFcalls, staticFcalls});
+ } catch (IllegalAccessException iax) {
+ throw new TestFailure("Illegal Access Exception");
+ }
}
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/test3.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/test3.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,102 +20,95 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import java.util.*;
-import java.lang.reflect.*;
-import nsk.share.TestFailure;
-
+import jdk.test.lib.Utils;
-class test3 extends test1
-{
+import java.lang.reflect.InvocationTargetException;
+import java.util.Random;
+import java.util.Vector;
- private final int[] MethodID = {Globals.MethodID_Array[3],Globals.MethodID_Array[4]};
- private static Random loopNumGen = new Random(Globals.RANDOM_SEED);
+class test3 extends test1 {
+
+ private final int[] MethodID = {Globals.MethodID_Array[3], Globals.MethodID_Array[4]};
+ private static Random loopNumGen = new Random(Utils.SEED);
private final int maxLoops = 10;
private int localNumLoops = loopNumGen.nextInt(maxLoops);
public void selfRecursion(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[1], summation);
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[1], summation);
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
+ }
- if (Globals.VERBOSE)
+ if (Globals.VERBOSE) {
System.out.println("test3.selfRecursion");
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ }
+
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
MethodData methodCallStr;
Long numFcalls;
Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0) //make a static call
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[1]));
- methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
- }
- else if (localNumLoops > 0) //make a recursive call
- {
- numFcalls = new Long(functionDepth.longValue()-1);
- staticFcalls = staticFunctionDepth;
- Globals.addFunctionIDToVector(MethodID[1], ID);
- localNumLoops--;
- selfRecursion(summation, ID, numFcalls, staticFcalls);
- return;
- }
- else //make a random call
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
+ // make a static call
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
+ } else if (localNumLoops > 0) { // make a recursive call
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ Globals.addFunctionIDToVector(MethodID[1], ID);
+ localNumLoops--;
+ selfRecursion(summation, ID, numFcalls, staticFcalls);
+ return;
+ } else { // make a random call
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
- localNumLoops = loopNumGen.nextInt(maxLoops); //get ready for the next call to this method
- }
+ // get ready for the next call to this method
+ localNumLoops = loopNumGen.nextInt(maxLoops);
+ }
Globals.addFunctionIDToVector(methodCallStr.id, ID);
Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
}
public void callMe(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[0], summation);
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[0], summation);
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
+ }
- if (Globals.VERBOSE)
+ if (Globals.VERBOSE) {
System.out.println("test3.callMe");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
MethodData methodCallStr;
Long numFcalls;
Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[0]));
- methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
Globals.addFunctionIDToVector(methodCallStr.id, ID);
Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
-
}
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/test4.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/test4.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,114 +20,106 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import java.util.*;
-import java.lang.reflect.*;
-import nsk.share.TestFailure;
-
+import java.lang.reflect.InvocationTargetException;
+import java.util.Vector;
-class test4 extends test2
-{
- private final int[] MethodID = {Globals.MethodID_Array[1],Globals.MethodID_Array[5], Globals.MethodID_Array[6]};
+class test4 extends test2 {
+ private final int[] MethodID = {Globals.MethodID_Array[1], Globals.MethodID_Array[5], Globals.MethodID_Array[6]};
- //this method verifies that a child can make a call to its parent
+ // this method verifies that a child can make a call to its parent
public void CallCallMe(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[1], summation);
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[1], summation);
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
+ }
- if (Globals.VERBOSE)
+ if (Globals.VERBOSE) {
System.out.println("test4.CallCallMe");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
MethodData methodCallStr;
Long numFcalls;
Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[1]));
- methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue()-1);
- staticFcalls = staticFunctionDepth;
- Globals.addFunctionIDToVector(MethodID[0], ID);
- super.callMe(summation, ID, numFcalls, staticFcalls);
- return;
- }
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ Globals.addFunctionIDToVector(MethodID[0], ID);
+ super.callMe(summation, ID, numFcalls, staticFcalls);
+ return;
+ }
Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
}
- //this method makes a Y fork in the method call structure
+ // this method makes a Y fork in the method call structure
public void callMe(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[2], summation);
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[2], summation);
- if (CGT.shouldFinish())
+ if (CGT.shouldFinish()) {
return;
-
- if (Globals.VERBOSE)
- System.out.println("test4.callMe");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ if (Globals.VERBOSE) {
+ System.out.println("test4.callMe");
+ }
+
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
MethodData methodCallStr;
Long numFcalls;
Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[2]));
- methodCallStr = Globals.returnNextStaticMethod(MethodID[2]);
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[2]);
+ } else {
+ long temp = functionDepth.longValue() - 2;
+ numFcalls = new Long(temp / 2);
+ staticFcalls = staticFunctionDepth;
+ if (Globals.VERBOSE) {
+ System.out.println(" test4.callMe - Starting Branch 1");
}
- else
- {
- long temp = functionDepth.longValue()-2;
- numFcalls = new Long(temp/2);
- staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
- if (Globals.VERBOSE)
- System.out.println(" test4.callMe - Starting Branch 1");
- methodCallStr = Globals.nextRandomMethod();
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
-
- if (CGT.shouldFinish())
- return;
+ if (CGT.shouldFinish()) {
+ return;
+ }
- temp -= temp/2;
- if (temp <0)
- {
- if (Globals.VERBOSE)
- System.out.println(" test4.callMe - Skipping Branch 2");
- return;
- }
- if (Globals.VERBOSE)
- System.out.println(" test4.callMe - Starting Branch 2");
- numFcalls = new Long(temp);
- methodCallStr = Globals.nextRandomMethod();
+ temp -= temp / 2;
+ if (temp < 0) {
+ if (Globals.VERBOSE) {
+ System.out.println(" test4.callMe - Skipping Branch 2");
+ }
+ return;
}
+ if (Globals.VERBOSE) {
+ System.out.println(" test4.callMe - Starting Branch 2");
+ }
+ numFcalls = new Long(temp);
+ methodCallStr = Globals.nextRandomMethod();
+ }
Globals.addFunctionIDToVector(methodCallStr.id, ID);
Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/test5.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/test5.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,320 +20,305 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import java.util.*;
-import java.lang.reflect.*;
+import jdk.test.lib.Utils;
import nsk.share.TestFailure;
-class test5
-{
- private final int[] MethodID = {Globals.MethodID_Array[7],
- Globals.MethodID_Array[8],
- Globals.MethodID_Array[9],
- Globals.MethodID_Array[10]};
- private static Random loopNumGen = new Random(Globals.RANDOM_SEED);
+import java.lang.reflect.InvocationTargetException;
+import java.util.Random;
+import java.util.Vector;
- private final int maxLoops = 12;
+class test5 {
+ private final int[] MethodID = {Globals.MethodID_Array[7],
+ Globals.MethodID_Array[8],
+ Globals.MethodID_Array[9],
+ Globals.MethodID_Array[10]};
+ private static Random loopNumGen = new Random(Utils.SEED);
- private long factorial(int n)
- {
- if(n>1)
- return(n*factorial(n-1));
- else
- return (1);
- }
+ private final int maxLoops = 12;
+
+ private long factorial(int n) {
+ if (n > 1) {
+ return (n * factorial(n - 1));
+ } else {
+ return (1);
+ }
+ }
- private long fibonacci(long num1, long num2, int n)
- {
- if (n <= 0)
- return(num2);
- else
- return (fibonacci(num2, num1+num2, n-1));
- }
+ private long fibonacci(long num1, long num2, int n) {
+ if (n <= 0) {
+ return (num2);
+ } else {
+ return (fibonacci(num2, num1 + num2, n - 1));
+ }
+ }
- private long combination(int n, int r)
- {
- if ((r==0) || (n==r))
- return 1;
- else
- return(combination(n-1, r) +combination(n - 1, r - 1));
- }
+ private long combination(int n, int r) {
+ if ((r == 0) || (n == r)) {
+ return 1;
+ } else {
+ return (combination(n - 1, r) + combination(n - 1, r - 1));
+ }
+ }
- private int[] pascalsTriangle(int[] source, int n)
- {
- if (n>0)
- {
- int sourceLength = source.length;
- int [] temp = new int[sourceLength +1];
- temp[0] = 1;
- temp[sourceLength] = 1;
-
- int j=1;
- for(int i = 0; i<(sourceLength - 1); i++)
- temp[j++] = source[i] + source[i+1];
+ private int[] pascalsTriangle(int[] source, int n) {
+ if (n > 0) {
+ int sourceLength = source.length;
+ int[] temp = new int[sourceLength + 1];
+ temp[0] = 1;
+ temp[sourceLength] = 1;
- return(pascalsTriangle(temp, n-1));
- }
- else
- return source;
- }
+ int j = 1;
+ for (int i = 0; i < (sourceLength - 1); i++) {
+ temp[j++] = source[i] + source[i + 1];
+ }
- private boolean verifyArray(int[] ArrayToBeVerified, int[] MasterArray)
- {
- if (ArrayToBeVerified.length != MasterArray.length)
- return false;
+ return pascalsTriangle(temp, n - 1);
+ } else {
+ return source;
+ }
+ }
- for (int i =0; i<MasterArray.length; i++)
- if (MasterArray[i] != ArrayToBeVerified[i])
- return false;
- return true;
- }
+ private boolean verifyArray(int[] ArrayToBeVerified, int[] MasterArray) {
+ if (ArrayToBeVerified.length != MasterArray.length) {
+ return false;
+ }
- private int[] verifyPascal(int n)
- {
- int [] pascalOut = new int[n+1];
- int [][] dataArray = new int[n+1][n+1];
+ for (int i = 0; i < MasterArray.length; i++) {
+ if (MasterArray[i] != ArrayToBeVerified[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
- for (int i = 0; i<=n; i++)
- {
- for (int j = 0; j<=n; j++)
- {
- if (j==0)
- dataArray[i][0] = 1;
- else if (j==i)
- dataArray[i][i] = 1;
- else if (j<i)
- dataArray[i][j] = dataArray[i-1][j-1] + dataArray[i-1][j];
- }
- }
+ private int[] verifyPascal(int n) {
+ int[] pascalOut = new int[n + 1];
+ int[][] dataArray = new int[n + 1][n + 1];
- int j = n; //could be a little more efficient
- for (int i = 0; i<=n; i++) //but not that important
- pascalOut[i] = dataArray[j][i];
- return pascalOut;
- }
+ for (int i = 0; i <= n; i++) {
+ for (int j = 0; j <= n; j++) {
+ if (j == 0) {
+ dataArray[i][0] = 1;
+ } else if (j == i) {
+ dataArray[i][i] = 1;
+ } else if (j < i) {
+ dataArray[i][j] = dataArray[i - 1][j - 1] + dataArray[i - 1][j];
+ }
+ }
+ }
- private long verifyFact(int n)
- {
- long answer = 1;
- for (int i=2; i<=n; i++)
- answer*=i;
- return answer;
- }
-
- private long verifyFibo(int n)
- {
- long num1=1;
- long num2=1;
+ // could be a little more efficient, but not that important
+ int j = n;
+ for (int i = 0; i <= n; i++) {
+ pascalOut[i] = dataArray[j][i];
+ }
+ return pascalOut;
+ }
- for (int i = 0; i< n; i++)
- {
- long temp = num1+num2;
- num1 = num2;
- num2 = temp;
- }
-
- return num2;
- }
+ private long verifyFact(int n) {
+ long answer = 1;
+ for (int i = 2; i <= n; i++) {
+ answer *= i;
+ }
+ return answer;
+ }
- private long verifyComb(int n, int r)
- {
- return(verifyFact(n)/(verifyFact(n-r)*verifyFact(r)));
- }
+ private long verifyFibo(int n) {
+ long num1 = 1;
+ long num2 = 1;
- public void factTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[0], summation);
+ for (int i = 0; i < n; i++) {
+ long temp = num1 + num2;
+ num1 = num2;
+ num2 = temp;
+ }
- if (CGT.shouldFinish())
- return;
+ return num2;
+ }
- if (Globals.VERBOSE)
- System.out.println("test5.factTest");
+ private long verifyComb(int n, int r) {
+ return (verifyFact(n) / (verifyFact(n - r) * verifyFact(r)));
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
- MethodData methodCallStr;
- Long numFcalls;
- Integer staticFcalls;
+ public void factTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[0], summation);
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[0]));
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
+ if (CGT.shouldFinish()) {
+ return;
+ }
+
+ if (Globals.VERBOSE) {
+ System.out.println("test5.factTest");
+ }
+
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
+ MethodData methodCallStr;
+ Long numFcalls;
+ Integer staticFcalls;
- int localNumLoops = loopNumGen.nextInt(maxLoops);
- long facFunctionValue = factorial(localNumLoops);
- long facVerValue = verifyFact(localNumLoops);
- if (facFunctionValue != facVerValue)
- {
- System.out.println("Factorial Computed Incorrectly");
- System.out.println("Specific Factorial Requested "+localNumLoops +"!");
- throw new TestFailure("Expected: " + facVerValue + " Actual "+ facFunctionValue);
- }
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- Globals.callMethod(methodCallStr,summation, ID, numFcalls, staticFcalls);
- }
+ int localNumLoops = loopNumGen.nextInt(maxLoops);
+ long facFunctionValue = factorial(localNumLoops);
+ long facVerValue = verifyFact(localNumLoops);
+ if (facFunctionValue != facVerValue) {
+ System.out.println("Factorial Computed Incorrectly");
+ System.out.println("Specific Factorial Requested " + localNumLoops + "!");
+ throw new TestFailure("Expected: " + facVerValue + " Actual " + facFunctionValue);
+ }
- public void fiboTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[1], summation);
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
+ }
- if (CGT.shouldFinish())
- return;
+ public void fiboTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[1], summation);
- if (Globals.VERBOSE)
- System.out.println("test5.fiboTest");
+ if (CGT.shouldFinish()) {
+ return;
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
- MethodData methodCallStr;
- Long numFcalls;
- Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
- int localNumLoops = loopNumGen.nextInt(maxLoops*3);
- long fiboFunctionValue = fibonacci(1,1,localNumLoops);
- long fiboVerValue = verifyFibo(localNumLoops);
- if (fiboFunctionValue != fiboVerValue)
- {
- System.out.println("Fibonacci Series Computed Incorrectly");
- System.out.println("Specific Digit Requested "+localNumLoops);
- throw new TestFailure("Expected: " + fiboVerValue + " Actual "+ fiboFunctionValue);
- }
+ if (Globals.VERBOSE) {
+ System.out.println("test5.fiboTest");
+ }
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- Globals.callMethod(methodCallStr,summation, ID, numFcalls, staticFcalls);
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
+ MethodData methodCallStr;
+ Long numFcalls;
+ Integer staticFcalls;
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[1]);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
+ int localNumLoops = loopNumGen.nextInt(maxLoops * 3);
+ long fiboFunctionValue = fibonacci(1, 1, localNumLoops);
+ long fiboVerValue = verifyFibo(localNumLoops);
+ if (fiboFunctionValue != fiboVerValue) {
+ System.out.println("Fibonacci Series Computed Incorrectly");
+ System.out.println("Specific Digit Requested " + localNumLoops);
+ throw new TestFailure("Expected: " + fiboVerValue + " Actual " + fiboFunctionValue);
+ }
+
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
+ }
- public void combTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[2], summation);
-
- if (CGT.shouldFinish())
- return;
-
- if (Globals.VERBOSE)
- System.out.println("test5.combTest");
+ public void combTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[2], summation);
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
- MethodData methodCallStr;
- Long numFcalls;
- Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
+ if (CGT.shouldFinish()) {
+ return;
+ }
+
+ if (Globals.VERBOSE) {
+ System.out.println("test5.combTest");
+ }
- methodCallStr = Globals.returnNextStaticMethod(MethodID[2]);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[2]));
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
- int n = loopNumGen.nextInt(maxLoops);
- int k = (n>0)?loopNumGen.nextInt(n):0;
- long combFunctionValue = combination(n, k);
- long combVerValue = verifyComb(n, k);
- if (combFunctionValue != combVerValue)
- {
- System.out.println("Combination Computed Incorrectly");
- System.out.println("N = " + n +"K = " + k);
- throw new TestFailure("Expected: " + combVerValue + " Actual "+ combFunctionValue);
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
+ MethodData methodCallStr;
+ Long numFcalls;
+ Integer staticFcalls;
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[2]);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
+ int n = loopNumGen.nextInt(maxLoops);
+ int k = (n > 0) ? loopNumGen.nextInt(n) : 0;
+ long combFunctionValue = combination(n, k);
+ long combVerValue = verifyComb(n, k);
+ if (combFunctionValue != combVerValue) {
+ System.out.println("Combination Computed Incorrectly");
+ System.out.println("N = " + n + "K = " + k);
+ throw new TestFailure("Expected: " + combVerValue + " Actual " + combFunctionValue);
+ }
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- Globals.callMethod(methodCallStr,summation, ID, numFcalls, staticFcalls);
- }
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
+ }
- public void pascalTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[3], summation);
+ public void pascalTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[3], summation);
- if (CGT.shouldFinish())
- return;
+ if (CGT.shouldFinish()) {
+ return;
+ }
-int [] x = new int[1 << 30];
-x[1 << 24] = 1;
+ if (Globals.VERBOSE) {
+ System.out.println("test5.pascalTest");
+ }
- if (Globals.VERBOSE)
- System.out.println("test5.pascalTest");
+ int[] x = new int[1 << 30];
+ x[1 << 24] = 1;
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
- MethodData methodCallStr;
- Long numFcalls;
- Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- methodCallStr = Globals.returnNextStaticMethod(MethodID[3]);
- //methodCallStr = Globals.nextStaticMethod(Globals.getIndexFromID(MethodID[3]));
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
- int num = loopNumGen.nextInt(maxLoops);
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
+ MethodData methodCallStr;
+ Long numFcalls;
+ Integer staticFcalls;
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[3]);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
+ int num = loopNumGen.nextInt(maxLoops);
- int[] pascalFunctionValue = pascalsTriangle(new int[] {1}, num);
- int[] pascalVerValue = verifyPascal(num);
- if (!verifyArray(pascalFunctionValue, pascalVerValue))
- {
- String temp = new String("Expected: ");
- for (int i=0; i<pascalVerValue.length; i++)
- temp += pascalVerValue[i] +", ";
- temp+= " Actual ";
- for (int i=0; i<pascalFunctionValue.length; i++)
- temp += pascalFunctionValue[i] +", ";
- System.out.println("Pascal Tringle Row Computed Incorrectly");
- System.out.println("Row Number " + num);
- throw new TestFailure(temp);
- }
+ int[] pascalFunctionValue = pascalsTriangle(new int[]{1}, num);
+ int[] pascalVerValue = verifyPascal(num);
+ if (!verifyArray(pascalFunctionValue, pascalVerValue)) {
+ StringBuilder temp = new StringBuilder("Expected: ");
+ for (int aPascalVerValue : pascalVerValue) {
+ temp.append(aPascalVerValue)
+ .append(", ");
+ }
+ temp.append(" Actual ");
+ for (int aPascalFunctionValue : pascalFunctionValue) {
+ temp.append(aPascalFunctionValue)
+ .append(", ");
+ }
+ System.out.println("Pascal Tringle Row Computed Incorrectly");
+ System.out.println("Row Number " + num);
+ throw new TestFailure(temp.toString());
+ }
- Globals.addFunctionIDToVector(methodCallStr.id, ID);
- Globals.callMethod(methodCallStr,summation, ID, numFcalls, staticFcalls);
- }
+ Globals.addFunctionIDToVector(methodCallStr.id, ID);
+ Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
+ }
}
--- a/test/hotspot/jtreg/vmTestbase/jit/graph/test6.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/jit/graph/test6.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -20,61 +20,58 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package jit.graph;
-import java.util.*;
-import java.lang.reflect.*;
+import jdk.test.lib.Utils;
import nsk.share.TestFailure;
-public class test6
-{
+import java.lang.reflect.InvocationTargetException;
+import java.util.Random;
+import java.util.Vector;
+
+public class test6 {
private static final int[] MethodID = {Globals.MethodID_Array[11]};
- private static Random localNumGen = new Random(Globals.RANDOM_SEED);
+ private static Random localNumGen = new Random(Utils.SEED);
private static final int maxEntries = 25;
- //flattens the binary tree into an array
- private void getSortedArray(Node root, int [] dataArray, int[] index)
- {
- if ((root != null) && (root!=RBTree.treeNull))
- {
- getSortedArray(root.getNode(Node.Left_son), dataArray, index);
- dataArray[index[0]++] = root.getKey();
- getSortedArray(root.getNode(Node.Right_son), dataArray, index);
- }
+ // flattens the binary tree into an array
+ private void getSortedArray(Node root, int[] dataArray, int[] index) {
+ if ((root != null) && (root != RBTree.treeNull)) {
+ getSortedArray(root.getNode(Node.Left_son), dataArray, index);
+ dataArray[index[0]++] = root.getKey();
+ getSortedArray(root.getNode(Node.Right_son), dataArray, index);
+ }
}
public synchronized void rbTest(Vector summation, Vector ID, Long functionDepth, Integer staticFunctionDepth)
- throws InvocationTargetException
- {
- Globals.appendSumToSumationVector(MethodID[0], summation);
-
- if (CGT.shouldFinish())
- return;
+ throws InvocationTargetException {
+ Globals.appendSumToSummationVector(MethodID[0], summation);
- if (Globals.VERBOSE)
+ if (CGT.shouldFinish()) {
+ return;
+ }
+ if (Globals.VERBOSE) {
System.out.println("test6.rbTest");
+ }
- if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0))
- {
- return;
- }
+ if ((functionDepth.longValue() <= 0) && (staticFunctionDepth.intValue() <= 0)) {
+ return;
+ }
MethodData methodCallStr;
Long numFcalls;
Integer staticFcalls;
- if (staticFunctionDepth.intValue() > 0)
- {
- numFcalls = functionDepth;
- staticFcalls = new Integer(staticFunctionDepth.intValue()-1);
- methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
- }
- else
- {
- numFcalls = new Long(functionDepth.longValue() -1);
- staticFcalls = staticFunctionDepth;
- methodCallStr = Globals.nextRandomMethod();
- }
+ if (staticFunctionDepth.intValue() > 0) {
+ numFcalls = functionDepth;
+ staticFcalls = new Integer(staticFunctionDepth.intValue() - 1);
+ methodCallStr = Globals.returnNextStaticMethod(MethodID[0]);
+ } else {
+ numFcalls = new Long(functionDepth.longValue() - 1);
+ staticFcalls = staticFunctionDepth;
+ methodCallStr = Globals.nextRandomMethod();
+ }
RBTree myTree = new RBTree();
int numElements = 1 + localNumGen.nextInt(maxEntries);
@@ -82,81 +79,64 @@
boolean insertArray[] = new boolean[numElements];
Vector temp = new Vector(numElements);
- for(int i=0; i<numElements; i++)
- { //code guarantees no duplicates
- int nextKey = localNumGen.nextInt(16385);
- while (temp.indexOf(new Integer(nextKey)) != -1)
- nextKey = localNumGen.nextInt(16385);
+ // code guarantees no duplicates
+ for (int i = 0; i < numElements; i++) {
+ int nextKey = localNumGen.nextInt(16385);
+ while (temp.indexOf(new Integer(nextKey)) != -1) {
+ nextKey = localNumGen.nextInt(16385);
+ }
- temp.addElement(new Integer(nextKey));
- dataArray[i] = nextKey;
+ temp.addElement(new Integer(nextKey));
+ dataArray[i] = nextKey;
- insertArray[i] = false;
- }
+ insertArray[i] = false;
+ }
temp = null;
int numLoops = 10 + localNumGen.nextInt(1024);
- for (int i=0; i<numLoops; i++)
- {
- int nextIndex = localNumGen.nextInt(numElements);
- if (!insertArray[nextIndex])
- {
- myTree.RBInsert(dataArray[nextIndex]);
- insertArray[nextIndex] = true;
- }
- else
- {
- myTree.RBDelete(dataArray[nextIndex]);
- insertArray[nextIndex] = false;
- }
+ for (int i = 0; i < numLoops; i++) {
+ int nextIndex = localNumGen.nextInt(numElements);
+ if (!insertArray[nextIndex]) {
+ myTree.RBInsert(dataArray[nextIndex]);
+ insertArray[nextIndex] = true;
+ } else {
+ myTree.RBDelete(dataArray[nextIndex]);
+ insertArray[nextIndex] = false;
}
+ }
int numValid = 0;
- for (int i = 0; i<numElements; i++)
- {
- Node searchNode = myTree.Search(dataArray[i]);
- if (insertArray[i] && (searchNode == RBTree.treeNull))
- {
- System.out.println("Valid Node Not Found in Binary Tree");
- System.out.println("Node " + dataArray[i]);
- System.exit(1);
- }
- else if ((!insertArray[i]) && (searchNode != RBTree.treeNull))
- {
- System.out.println("Deleted Node Found in Binary Tree");
- System.out.println("Node " + dataArray[i]);
- System.exit(1);
- }
- else if (insertArray[i])
- numValid++;
- insertArray[i] = true; //so that verification is only done once
+ for (int i = 0; i < numElements; i++) {
+ Node searchNode = myTree.Search(dataArray[i]);
+ if (insertArray[i] && (searchNode == RBTree.treeNull)) {
+ throw new TestFailure("Valid Node Not Found in Binary Tree. Node " + dataArray[i]);
+ } else if ((!insertArray[i]) && (searchNode != RBTree.treeNull)) {
+ throw new TestFailure("Deleted Node Found in Binary Tree. Node " + dataArray[i]);
+ } else if (insertArray[i]) {
+ numValid++;
}
+ // so that verification is only done once
+ insertArray[i] = true;
+ }
- int [] sortedArray = new int[numValid];
- getSortedArray(myTree.getRoot(), sortedArray, new int [] {0});
+ int[] sortedArray = new int[numValid];
+ getSortedArray(myTree.getRoot(), sortedArray, new int[]{0});
- for (int i=1; i<numValid; i++)
- if (sortedArray[i] <= sortedArray[i-1])
- {
- String outStr = new String("Actual ");
- for (int j=0; j<sortedArray.length; j++)
- outStr += sortedArray[j] +", ";
- System.out.println("Binary Tree Property Not Held");
- System.out.println("Root " + myTree.getRoot().getKey());
- System.out.println(outStr);
- System.exit(1);
+ for (int i = 1; i < numValid; i++) {
+ if (sortedArray[i] <= sortedArray[i - 1]) {
+ StringBuilder outStr = new StringBuilder("Actual ");
+ for (int aSortedArray : sortedArray) {
+ outStr.append(aSortedArray)
+ .append(", ");
}
-
- //Should make more memory available for future instances
- myTree = null;
- sortedArray = null;
- dataArray = null;
- insertArray = null;
-// System.gc();
+ System.out.println("Binary Tree Property Not Held");
+ System.out.println("Root " + myTree.getRoot()
+ .getKey());
+ throw new TestFailure(outStr.toString());
+ }
+ }
Globals.addFunctionIDToVector(methodCallStr.id, ID);
- Globals.callMethod(methodCallStr,summation, ID, numFcalls, staticFcalls);
-
-
+ Globals.callMethod(methodCallStr, summation, ID, numFcalls, staticFcalls);
}
}
--- a/test/jdk/ProblemList.txt Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/ProblemList.txt Wed Oct 16 11:23:46 2019 +0200
@@ -884,6 +884,7 @@
jdk/jfr/event/io/EvilInstrument.java 8221331 generic-all
jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java 8228990,8229370 generic-all
jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic-all
+jdk/jfr/event/oldobject/TestLargeRootSet.java 8205651 generic-all
############################################################################
--- a/test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java Wed Oct 16 11:23:46 2019 +0200
@@ -151,9 +151,13 @@
reference.
*/
class Target {
+
+ static Class<?> topLevelHostA; // Prevent unloading of the class
+
// We have to load all of the variants of the classes that we will
// attempt to redefine. This requires some in-memory compilation
// and use of additional classloaders.
+
public static void main(String[] args) throws Throwable {
String origin = args[0];
System.out.println("Target: Testing original Host class from " + origin);
@@ -178,7 +182,7 @@
String hostA = "public class " + name + " {}";
byte[] bytes = InMemoryJavaCompiler.compile(name, hostA);
// And we have to load this into a new classloader
- Class<?> topLevelHostA = ByteCodeLoader.load(name, bytes);
+ topLevelHostA = ByteCodeLoader.load(name, bytes);
// The loaded class has not been linked (as per ClassLoader.resolveClass)
// and so will be filtered out by VirtualMachine.allClasses(). There are
// a number of ways to force linking - this is the simplest.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/FontMetrics/SpaceAdvance.java Wed Oct 16 11:23:46 2019 +0200
@@ -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.
+ */
+
+/*
+ * @test
+ * @bug 8227662
+ */
+
+import java.awt.Font;
+import java.awt.FontMetrics ;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+public class SpaceAdvance {
+ public static void main(String[] args) throws Exception {
+
+ BufferedImage bi = new BufferedImage(1,1,1);
+ Graphics2D g2d = bi.createGraphics();
+ Font font = new Font(Font.DIALOG, Font.PLAIN, 12);
+ if (!font.canDisplay(' ')) {
+ return;
+ }
+ g2d.setFont(font);
+ FontMetrics fm = g2d.getFontMetrics();
+ if (fm.charWidth(' ') == 0) {
+ throw new RuntimeException("Space has char width of 0");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Toolkit/GetMulticlickTime/GetMulticlickTime.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * 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.Toolkit;
+
+/**
+ * @test
+ * @key headful
+ * @bug 4559047 7124404
+ * @summary Solaris/Linux/macOS do not set awt.multiClickInterval desktop property
+ */
+public final class GetMulticlickTime {
+
+ public static void main(final String[] args) {
+ Integer time = (Integer) Toolkit.getDefaultToolkit()
+ .getDesktopProperty("awt.multiClickInterval");
+ if (time == null || time <= 0 || time > 30_000) {
+ throw new RuntimeException("awt.multiClickInterval:" + time);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/DrawImage/IncorrectManagedImageSourceOffset.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import sun.awt.image.SunWritableRaster;
+
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8029253 6207877
+ * @summary Tests asymmetric source offsets when managed image is drawn to VI.
+ * Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ * @modules java.desktop/sun.awt.image
+ * @run main/othervm -Dsun.java2d.accthreshold=0 IncorrectManagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=1 IncorrectManagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=2 IncorrectManagedImageSourceOffset
+ */
+public final class IncorrectManagedImageSourceOffset {
+
+ // See the same test for unmanaged images: IncorrectUnmanagedImageSourceOffset
+
+ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+ TYPE_4BYTE_ABGR_PRE,
+ /*TYPE_USHORT_565_RGB,
+ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+ TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+ TYPE_BYTE_INDEXED, TYPE_CUSTOM};
+ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+ public static void main(final String[] args) throws IOException {
+ for (final int viType : TRANSPARENCIES) {
+ for (final int biType : TYPES) {
+ BufferedImage bi = makeManagedBI(biType);
+ fill(bi);
+ test(bi, viType);
+ }
+ }
+ }
+
+ private static void test(BufferedImage bi, int type)
+ throws IOException {
+ GraphicsEnvironment ge = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ VolatileImage vi = gc.createCompatibleVolatileImage(511, 255, type);
+ BufferedImage gold = gc.createCompatibleImage(511, 255, type);
+ // draw to compatible Image
+ Graphics2D big = gold.createGraphics();
+ // force scaled blit
+ big.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
+ big.dispose();
+ // draw to volatile image
+ BufferedImage snapshot;
+ while (true) {
+ vi.validate(gc);
+ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ Graphics2D vig = vi.createGraphics();
+ // force scaled blit
+ vig.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
+ vig.dispose();
+ snapshot = vi.getSnapshot();
+ if (vi.contentsLost()) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ break;
+ }
+ // validate images
+ for (int x = 7; x < 127; ++x) {
+ for (int y = 11; y < 111; ++y) {
+ if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+ ImageIO.write(gold, "png", new File("gold.png"));
+ ImageIO.write(snapshot, "png", new File("bi.png"));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+
+ private static BufferedImage makeManagedBI(final int type) {
+ final BufferedImage bi;
+ if (type == TYPE_CUSTOM) {
+ bi = makeCustomManagedBI();
+ } else {
+ bi = new BufferedImage(511, 255, type);
+ }
+ bi.setAccelerationPriority(1.0f);
+ return bi;
+ }
+
+ /**
+ * Returns the custom buffered image, which mostly identical to
+ * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+ * This means that the raster will have gaps, between the rows.
+ */
+ private static BufferedImage makeCustomManagedBI() {
+ int w = 511, h = 255;
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8};
+ int[] bOffs = {2, 1, 0};
+ ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+ WritableRaster raster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+ w * 3 + 2, 3, bOffs, null);
+ BufferedImage bi = new BufferedImage(colorModel, raster, true, null);
+ SunWritableRaster.makeTrackable(raster.getDataBuffer());
+ SunWritableRaster.markDirty(bi);
+ return bi;
+ }
+
+ private static void fill(final Image image) {
+ final Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setComposite(AlphaComposite.Src);
+ for (int i = 0; i < image.getHeight(null); ++i) {
+ graphics.setColor(new Color(i, 0, 0));
+ graphics.fillRect(0, i, image.getWidth(null), 1);
+ }
+ graphics.dispose();
+ }
+}
--- a/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -27,30 +27,52 @@
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
+import java.awt.image.Raster;
import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
-import static java.awt.Transparency.*;
-import static java.awt.image.BufferedImage.*;
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
/**
* @test
* @key headful
- * @bug 8029253
+ * @bug 8029253 6207877
* @summary Tests asymmetric source offsets when unmanaged image is drawn to VI.
* Results of the blit to compatibleImage are used for comparison.
* @author Sergey Bylokhov
+ * @run main/othervm IncorrectUnmanagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.uiScale=1 IncorrectUnmanagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.uiScale=2 IncorrectUnmanagedImageSourceOffset
*/
public final class IncorrectUnmanagedImageSourceOffset {
+ // See the same test for managed images: IncorrectManagedImageSourceOffset
+
private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
@@ -58,7 +80,7 @@
/*TYPE_USHORT_565_RGB,
TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
- TYPE_BYTE_INDEXED};
+ TYPE_BYTE_INDEXED, TYPE_CUSTOM};
private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
public static void main(final String[] args) throws IOException {
@@ -122,7 +144,12 @@
}
private static BufferedImage makeUnmanagedBI(final int type) {
- final BufferedImage bi = new BufferedImage(511, 255, type);
+ final BufferedImage bi;
+ if (type == TYPE_CUSTOM) {
+ bi = makeCustomUnmanagedBI();
+ } else {
+ bi = new BufferedImage(511, 255, type);
+ }
final DataBuffer db = bi.getRaster().getDataBuffer();
if (db instanceof DataBufferInt) {
((DataBufferInt) db).getData();
@@ -130,15 +157,30 @@
((DataBufferShort) db).getData();
} else if (db instanceof DataBufferByte) {
((DataBufferByte) db).getData();
- } else {
- try {
- bi.setAccelerationPriority(0.0f);
- } catch (final Throwable ignored) {
- }
}
+ bi.setAccelerationPriority(0.0f);
return bi;
}
+ /**
+ * Returns the custom buffered image, which mostly identical to
+ * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+ * This means that the raster will have gaps, between the rows.
+ */
+ private static BufferedImage makeCustomUnmanagedBI() {
+ int w = 511, h = 255;
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8};
+ int[] bOffs = {2, 1, 0};
+ ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+ WritableRaster raster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+ w * 3 + 2, 3, bOffs, null);
+ return new BufferedImage(colorModel, raster, true, null);
+ }
+
private static void fill(final Image image) {
final Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setComposite(AlphaComposite.Src);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/DrawImage/SimpleManagedImage.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import sun.awt.image.SunWritableRaster;
+
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8029253 6207877
+ * @summary Tests the case when managed image is drawn to VI.
+ * Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ * @modules java.desktop/sun.awt.image
+ * @run main/othervm -Dsun.java2d.accthreshold=0 SimpleManagedImage
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=1 SimpleManagedImage
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=2 SimpleManagedImage
+ */
+public final class SimpleManagedImage {
+
+ // See the same test for unmanaged images: SimpleUnmanagedImage
+
+ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+ TYPE_4BYTE_ABGR_PRE,
+ /*TYPE_USHORT_565_RGB,
+ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+ TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+ TYPE_BYTE_INDEXED, TYPE_CUSTOM};
+ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+ public static void main(final String[] args) throws IOException {
+ for (final int viType : TRANSPARENCIES) {
+ for (final int biType : TYPES) {
+ BufferedImage bi = makeManagedBI(biType);
+ fill(bi);
+ test(bi, viType);
+ }
+ }
+ }
+
+ private static void test(BufferedImage bi, int type)
+ throws IOException {
+ GraphicsEnvironment ge = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ VolatileImage vi = gc.createCompatibleVolatileImage(1000, 1000, type);
+ BufferedImage gold = gc.createCompatibleImage(1000, 1000, type);
+ // draw to compatible Image
+ init(gold);
+ Graphics2D big = gold.createGraphics();
+ big.drawImage(bi, 7, 11, null);
+ big.dispose();
+ // draw to volatile image
+ BufferedImage snapshot;
+ while (true) {
+ vi.validate(gc);
+ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ init(vi);
+ Graphics2D vig = vi.createGraphics();
+ vig.drawImage(bi, 7, 11, null);
+ vig.dispose();
+ snapshot = vi.getSnapshot();
+ if (vi.contentsLost()) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ break;
+ }
+ // validate images
+ for (int x = 0; x < 1000; ++x) {
+ for (int y = 0; y < 1000; ++y) {
+ if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+ ImageIO.write(gold, "png", new File("gold.png"));
+ ImageIO.write(snapshot, "png", new File("bi.png"));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+
+ private static BufferedImage makeManagedBI(final int type) {
+ final BufferedImage bi;
+ if (type == TYPE_CUSTOM) {
+ bi = makeCustomManagedBI();
+ } else {
+ bi = new BufferedImage(511, 255, type);
+ }
+ bi.setAccelerationPriority(1.0f);
+ return bi;
+ }
+
+ /**
+ * Returns the custom buffered image, which mostly identical to
+ * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+ * This means that the raster will have gaps, between the rows.
+ */
+ private static BufferedImage makeCustomManagedBI() {
+ int w = 511, h = 255;
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8};
+ int[] bOffs = {2, 1, 0};
+ ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+ WritableRaster raster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+ w * 3 + 2, 3, bOffs, null);
+ BufferedImage bi = new BufferedImage(colorModel, raster, true, null);
+ SunWritableRaster.makeTrackable(raster.getDataBuffer());
+ SunWritableRaster.markDirty(bi);
+ return bi;
+ }
+
+ private static void init(final Image image) {
+ final Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setComposite(AlphaComposite.Src);
+ graphics.setColor(new Color(0, 0, 0, 0));
+ graphics.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
+ graphics.dispose();
+ }
+
+ private static void fill(final Image image) {
+ final Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setComposite(AlphaComposite.Src);
+ for (int i = 0; i < image.getHeight(null); ++i) {
+ graphics.setColor(new Color(i, 0, 0));
+ graphics.fillRect(0, i, image.getWidth(null), 1);
+ }
+ graphics.dispose();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/DrawImage/SimpleUnmanagedImage.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.Raster;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8029253 6207877
+ * @summary Tests the case when unmanaged image is drawn to VI.
+ * Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ * @run main/othervm SimpleUnmanagedImage
+ * @run main/othervm -Dsun.java2d.uiScale=1 SimpleUnmanagedImage
+ * @run main/othervm -Dsun.java2d.uiScale=2 SimpleUnmanagedImage
+ */
+public final class SimpleUnmanagedImage {
+
+ // See the same test for managed images: SimpleManagedImage
+
+ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+ TYPE_4BYTE_ABGR_PRE,
+ /*TYPE_USHORT_565_RGB,
+ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+ TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+ TYPE_BYTE_INDEXED, TYPE_CUSTOM};
+ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+ public static void main(final String[] args) throws IOException {
+ for (final int viType : TRANSPARENCIES) {
+ for (final int biType : TYPES) {
+ BufferedImage bi = makeUnmanagedBI(biType);
+ fill(bi);
+ test(bi, viType);
+ }
+ }
+ }
+
+ private static void test(BufferedImage bi, int type)
+ throws IOException {
+ GraphicsEnvironment ge = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ VolatileImage vi = gc.createCompatibleVolatileImage(1000, 1000, type);
+ BufferedImage gold = gc.createCompatibleImage(1000, 1000, type);
+ // draw to compatible Image
+ init(gold);
+ Graphics2D big = gold.createGraphics();
+ big.drawImage(bi, 7, 11, null);
+ big.dispose();
+ // draw to volatile image
+ BufferedImage snapshot;
+ while (true) {
+ vi.validate(gc);
+ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ init(vi);
+ Graphics2D vig = vi.createGraphics();
+ vig.drawImage(bi, 7, 11, null);
+ vig.dispose();
+ snapshot = vi.getSnapshot();
+ if (vi.contentsLost()) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ break;
+ }
+ // validate images
+ for (int x = 0; x < 1000; ++x) {
+ for (int y = 0; y < 1000; ++y) {
+ if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+ ImageIO.write(gold, "png", new File("gold.png"));
+ ImageIO.write(snapshot, "png", new File("bi.png"));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+
+ private static BufferedImage makeUnmanagedBI(final int type) {
+ final BufferedImage bi;
+ if (type == TYPE_CUSTOM) {
+ bi = makeCustomUnmanagedBI();
+ } else {
+ bi = new BufferedImage(511, 255, type);
+ }
+ final DataBuffer db = bi.getRaster().getDataBuffer();
+ if (db instanceof DataBufferInt) {
+ ((DataBufferInt) db).getData();
+ } else if (db instanceof DataBufferShort) {
+ ((DataBufferShort) db).getData();
+ } else if (db instanceof DataBufferByte) {
+ ((DataBufferByte) db).getData();
+ }
+ bi.setAccelerationPriority(0.0f);
+ return bi;
+ }
+
+ /**
+ * Returns the custom buffered image, which mostly identical to
+ * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+ * This means that the raster will have gaps, between the rows.
+ */
+ private static BufferedImage makeCustomUnmanagedBI() {
+ int w = 511, h = 255;
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8};
+ int[] bOffs = {2, 1, 0};
+ ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+ WritableRaster raster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+ w * 3 + 2, 3, bOffs, null);
+ return new BufferedImage(colorModel, raster, true, null);
+ }
+
+ private static void init(final Image image) {
+ final Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setComposite(AlphaComposite.Src);
+ graphics.setColor(new Color(0, 0, 0, 0));
+ graphics.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
+ graphics.dispose();
+ }
+
+ private static void fill(final Image image) {
+ final Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setComposite(AlphaComposite.Src);
+ for (int i = 0; i < image.getHeight(null); ++i) {
+ graphics.setColor(new Color(i, 0, 0));
+ graphics.fillRect(0, i, image.getWidth(null), 1);
+ }
+ graphics.dispose();
+ }
+}
--- a/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 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
@@ -23,7 +23,7 @@
/*
@test
- @bug 4386025
+ @bug 4386025 8231243
@summary fonts not in win32 font directory print incorrectly.
@author prr: area=PrinterJob
@run main/manual CustomFont
@@ -83,12 +83,13 @@
Font customFont;
public CustomFont() {
try {
- FileInputStream fin = new FileInputStream("A.ttf");
+ String dir = System.getProperty("test.src", ".");
+ String fileName = dir + File.separator + "A.ttf";
+ FileInputStream fin = new FileInputStream(fileName);
Font cf = Font.createFont(Font.TRUETYPE_FONT, fin);
customFont = cf.deriveFont(Font.PLAIN, 14);
} catch (Exception ioe) {
- System.err.println(ioe.getMessage());
- customFont = new Font("serif", Font.PLAIN, 14);
+ throw new RuntimeException(ioe);
}
}
@@ -99,7 +100,7 @@
g2D.setColor(Color.black);
g2D.setFont(customFont);
- String str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ String str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
g.drawString(str, 100, 100);
return Printable.PAGE_EXISTS;
--- a/test/jdk/java/io/ObjectInputStream/ResolveProxyClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/ObjectInputStream/ResolveProxyClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, 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
@@ -36,7 +36,6 @@
* @run main ResolveProxyClass
*/
-import java.lang.reflect.*;
import java.io.*;
public class ResolveProxyClass {
@@ -52,7 +51,7 @@
super();
}
- protected Class resolveProxyClass(String[] interfaces)
+ protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException
{
return super.resolveProxyClass(interfaces);
@@ -82,7 +81,7 @@
ClassLoader expectedLoader = ResolveProxyClass.class.getClassLoader();
TestObjectInputStream in = new TestObjectInputStream();
- Class proxyClass = in.resolveProxyClass(
+ Class<?> proxyClass = in.resolveProxyClass(
new String[] { Runnable.class.getName() });
ClassLoader proxyLoader = proxyClass.getClassLoader();
System.err.println("proxy class \"" + proxyClass +
--- a/test/jdk/java/io/ObjectInputStream/TestObjectStreamClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/ObjectInputStream/TestObjectStreamClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -58,6 +58,8 @@
}
static class TestClass implements Serializable {
+ private static final long serialVersionUID = 1L;
+
String str = "hello world";
}
--- a/test/jdk/java/io/Serializable/ClassCastExceptionDetail/Read.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/ClassCastExceptionDetail/Read.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, 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
@@ -36,7 +36,9 @@
private Float bar;
}
-class Gub extends Foo {}
+class Gub extends Foo {
+ private static final long serialVersionUID = 1L;
+}
public class Read {
public static void main(String[] args) throws Exception {
--- a/test/jdk/java/io/Serializable/ClassCastExceptionDetail/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/ClassCastExceptionDetail/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -41,10 +41,12 @@
class Foo implements Serializable {
private static final long serialVersionUID = 0L;
- private Integer bar = new Integer(0);
+ private Integer bar = 0;
}
-class Gub extends Foo {}
+class Gub extends Foo {
+ private static final long serialVersionUID = 1L;
+}
public class Write {
public static void main(String[] args) throws Exception {
--- a/test/jdk/java/io/Serializable/GetField/Read2.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/GetField/Read2.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -41,6 +41,7 @@
float f;
double d;
String str;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object extra;
private void readObject(ObjectInputStream in)
--- a/test/jdk/java/io/Serializable/InvalidClassException/noargctor/DefaultPackage.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/InvalidClassException/noargctor/DefaultPackage.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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
@@ -56,24 +56,33 @@
class DefaultPublicSerializable
extends DefaultPackagePublicConstructor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
};
class DefaultProtectedSerializable
extends DefaultPackageProtectedConstructor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
};
class DefaultAccessSerializable
extends DefaultPackageDefaultAccessConstructor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class DefaultPrivateSerializable
extends DefaultPackagePrivateConstructor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
DefaultPrivateSerializable() {
@@ -82,6 +91,8 @@
};
class ExternalizablePublicConstructor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
public ExternalizablePublicConstructor() {
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -92,7 +103,10 @@
}
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class ExternalizableProtectedConstructor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
protected ExternalizableProtectedConstructor() {
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -103,7 +117,10 @@
}
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class ExternalizableAccessConstructor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
ExternalizableAccessConstructor() {
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -114,7 +131,10 @@
}
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class ExternalizablePrivateConstructor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
private ExternalizablePrivateConstructor() {
}
public ExternalizablePrivateConstructor(int i) {
--- a/test/jdk/java/io/Serializable/InvalidClassException/noargctor/Serialize/SubclassAcrossPackage.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/InvalidClassException/noargctor/Serialize/SubclassAcrossPackage.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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
@@ -34,18 +34,24 @@
class PublicSerializable
extends NonSerializable.PublicCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
};
class ProtectedSerializable
extends NonSerializable.ProtectedCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
};
class DifferentPackageSerializable
extends NonSerializable.PackageCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
DifferentPackageSerializable() {
super(1);
@@ -55,11 +61,15 @@
class SamePackageSerializable
extends Serialize.SamePackageCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
SamePackageSerializable() {
}
};
class SamePackageProtectedCtor {
+ private static final long serialVersionUID = 1L;
+
protected SamePackageProtectedCtor() {
}
};
@@ -67,12 +77,16 @@
class SamePackageProtectedSerializable
extends Serialize.SamePackageProtectedCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
SamePackageProtectedSerializable() {
}
};
class SamePackagePrivateCtor {
+ private static final long serialVersionUID = 1L;
+
private SamePackagePrivateCtor() {
}
public SamePackagePrivateCtor(int l) {
@@ -82,6 +96,8 @@
class SamePackagePrivateSerializable
extends Serialize.SamePackagePrivateCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
SamePackagePrivateSerializable() {
super(1);
}
@@ -90,6 +106,8 @@
class PrivateSerializable
extends NonSerializable.PrivateCtor implements Serializable
{
+ private static final long serialVersionUID = 1L;
+
int field1 = 5;
PrivateSerializable() {
@@ -98,6 +116,8 @@
};
class ExternalizablePublicCtor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
public ExternalizablePublicCtor() {
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -108,7 +128,10 @@
}
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class ExternalizableProtectedCtor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
protected ExternalizableProtectedCtor() {
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -119,7 +142,10 @@
}
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class ExternalizablePackageCtor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
ExternalizablePackageCtor() {
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -130,7 +156,10 @@
}
};
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class ExternalizablePrivateCtor implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
private ExternalizablePrivateCtor() {
}
public ExternalizablePrivateCtor(int i) {
--- a/test/jdk/java/io/Serializable/NPEProvoker/NPEProvoker.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/NPEProvoker/NPEProvoker.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2010, 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
@@ -41,6 +41,8 @@
import java.util.ArrayList;
public class NPEProvoker implements java.io.Externalizable {
+ private static final long serialVersionUID = 1L;
+
private String test = "test";
public void readExternal(ObjectInput in) throws IOException,
--- a/test/jdk/java/io/Serializable/NoClassDefFoundErrorTrap/NoClassDefFoundErrorTrap.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/NoClassDefFoundErrorTrap/NoClassDefFoundErrorTrap.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -40,7 +40,9 @@
private static NoClassDefFoundError ncdfe;
public interface Bar {}
- public static class Foo implements Bar, java.io.Serializable {}
+ public static class Foo implements Bar, java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+ }
/**
* Test subclass of ObjectInputStream that overrides resolveClass
@@ -55,7 +57,7 @@
super(in);
}
- protected Class resolveClass(ObjectStreamClass desc)
+ protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String name = desc.getName();
--- a/test/jdk/java/io/Serializable/PutField/Write2.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/PutField/Write2.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -44,6 +44,7 @@
new ObjectStreamField("s2", String.class)
};
+ @SuppressWarnings("deprecation")
private void writeObject(ObjectOutputStream out) throws IOException {
ObjectOutputStream.PutField fields = out.putFields();
fields.put("s1", "qwerty");
--- a/test/jdk/java/io/Serializable/badSerialPersistentField/BadSerialPersistentField.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/badSerialPersistentField/BadSerialPersistentField.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,12 +31,16 @@
import java.io.*;
class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("nonexistent", int.class)
};
}
class B implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("mismatched", int.class)
};
@@ -44,6 +48,8 @@
}
class C implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("existent", int.class)
};
--- a/test/jdk/java/io/Serializable/badSerialVersionUID/BadSerialVersionUID.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/badSerialVersionUID/BadSerialVersionUID.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -32,42 +32,50 @@
import java.io.*;
class Z implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final boolean serialVersionUID = false;
}
class B implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final byte serialVersionUID = 5;
}
class C implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final char serialVersionUID = 5;
}
class S implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final short serialVersionUID = 5;
}
class I implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final int serialVersionUID = 5;
}
class F implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final float serialVersionUID = 5.0F;
}
class D implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final double serialVersionUID = 5.0;
}
class L implements Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final Object serialVersionUID = "5";
}
public class BadSerialVersionUID {
public static void main(String[] args) throws Exception {
- Class[] ignore = { Z.class, F.class, D.class, L.class };
- Class[] convert = { B.class, C.class, S.class, I.class };
+ Class<?>[] ignore = { Z.class, F.class, D.class, L.class };
+ Class<?>[] convert = { B.class, C.class, S.class, I.class };
for (int i = 0; i < ignore.length; i++) {
ObjectStreamClass.lookup(ignore[i]).getSerialVersionUID();
--- a/test/jdk/java/io/Serializable/badSubstByReplace/BadSubstByReplace.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/badSubstByReplace/BadSubstByReplace.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, 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,11 +29,16 @@
*/
import java.io.*;
-class A implements Serializable {}
+class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+}
-class B implements Serializable {}
+class B implements Serializable {
+ private static final long serialVersionUID = 1L;
+}
class Container implements Serializable {
+ private static final long serialVersionUID = 1L;
A a = new A();
}
--- a/test/jdk/java/io/Serializable/checkModifiers/CheckModifiers.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/checkModifiers/CheckModifiers.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, 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
@@ -36,7 +36,10 @@
import java.io.*;
class TestClass1 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// Missing the "final" modifier
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("field1", Integer.class),
new ObjectStreamField("field2", Double.TYPE),
@@ -58,7 +61,7 @@
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField pfields = ois.readFields();
- field1 = (Integer) pfields.get("field1", new Integer(100));
+ field1 = (Integer) pfields.get("field1", Integer.valueOf(100));
field2 = pfields.get("field2", 99.99);
/* These fields must be present in the stream */
@@ -79,7 +82,10 @@
class TestClass2 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// public instead of private
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
public static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("field1", Integer.class),
new ObjectStreamField("field2", Double.TYPE),
@@ -101,7 +107,7 @@
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField pfields = ois.readFields();
- field1 = (Integer) pfields.get("field1", new Integer(100));
+ field1 = (Integer) pfields.get("field1", Integer.valueOf(100));
field2 = pfields.get("field2", 99.99);
/* These fields must be present in the stream */
@@ -121,7 +127,10 @@
};
class TestClass3 implements Serializable{
+ private static final long serialVersionUID = 1L;
+
// Not of type ObjectStreamField
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private final String[] serialPersistentFields = {"Foo","Foobar"};;
Integer field1;
double field2;
@@ -139,7 +148,7 @@
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField pfields = ois.readFields();
- field1 = (Integer) pfields.get("field1", new Integer(100));
+ field1 = (Integer) pfields.get("field1", Integer.valueOf(100));
field2 = pfields.get("field2", 99.99);
field3 = pfields.get("field3", 99);
field4 = (String) pfields.get("field4", "Default string");
@@ -156,6 +165,8 @@
};
class TestClass4 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// Correct format
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("field1", Integer.class),
@@ -178,7 +189,7 @@
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField pfields = ois.readFields();
- field1 = (Integer) pfields.get("field1", new Integer(100));
+ field1 = (Integer) pfields.get("field1", Integer.valueOf(100));
field2 = pfields.get("field2", 99.99);
try {
@@ -199,16 +210,16 @@
public class CheckModifiers {
public static void main(String[] args)
throws ClassNotFoundException, IOException{
- TestClass1 tc1 = new TestClass1(new Integer(100), 25.56, 2000,
+ TestClass1 tc1 = new TestClass1(100, 25.56, 2000,
new String("Test modifiers of serialPersistentFields"));
- TestClass2 tc2 = new TestClass2(new Integer(100), 25.56, 2000,
+ TestClass2 tc2 = new TestClass2(100, 25.56, 2000,
new String("Test modifiers of serialPersistentFields"));
- TestClass3 tc3 = new TestClass3(new Integer(100), 25.56, 2000,
+ TestClass3 tc3 = new TestClass3(100, 25.56, 2000,
new String("Test Type of serialPersistentFields"));
- TestClass4 tc4 = new TestClass4(new Integer(100), 25.56, 2000,
+ TestClass4 tc4 = new TestClass4(100, 25.56, 2000,
new String("Test modifiers of serialPersistentFields"));
--- a/test/jdk/java/io/Serializable/class/SerialA_2/A.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/class/SerialA_2/A.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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
@@ -24,7 +24,7 @@
import java.io.Serializable;
public class A implements Serializable {
- static final long serialVersionUID = 746945609796141988L;
+ private static final long serialVersionUID = 746945609796141988L;
int field1;
int field2;
--- a/test/jdk/java/io/Serializable/classDescFlagConflict/Foo.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/classDescFlagConflict/Foo.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -30,6 +30,8 @@
import java.io.*;
public class Foo implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
public void writeExternal(ObjectOutput out) throws IOException {}
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {}
--- a/test/jdk/java/io/Serializable/classDescGetField/GetField.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/classDescGetField/GetField.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -33,6 +33,8 @@
import java.io.*;
public class GetField implements Serializable{
+ private static final long serialVersionUID = 1L;
+
String str;
int i;
--- a/test/jdk/java/io/Serializable/classDescHooks/CNFException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/classDescHooks/CNFException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -47,7 +47,7 @@
public static void main(String[] args) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(new Integer(5));
+ oout.writeObject(5);
oout.close();
ObjectInputStream oin =
new CNFInputStream(new ByteArrayInputStream(bout.toByteArray()));
--- a/test/jdk/java/io/Serializable/classDescHooks/ClassDescHooks.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/classDescHooks/ClassDescHooks.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, 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
@@ -32,9 +32,9 @@
class Foo implements Serializable {
private static final long serialVersionUID = 1L;
- Short s = new Short((short) 1);
- Integer i = new Integer(2);
- Long l = new Long(3);
+ Short s = (short) 1;
+ Integer i = 2;
+ Long l = 3L;
public boolean equals(Object obj) {
if (obj instanceof Foo) {
@@ -43,6 +43,10 @@
}
return false;
}
+
+ public int hashCode() {
+ return i;
+ }
}
class CustomOutputStream extends ObjectOutputStream {
--- a/test/jdk/java/io/Serializable/classDescHooks/ExternLoopback.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/classDescHooks/ExternLoopback.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -32,9 +32,9 @@
import java.util.*;
class LoopbackOutputStream extends ObjectOutputStream {
- LinkedList descs;
+ LinkedList<ObjectStreamClass> descs;
- LoopbackOutputStream(OutputStream out, LinkedList descs)
+ LoopbackOutputStream(OutputStream out, LinkedList<ObjectStreamClass> descs)
throws IOException
{
super(out);
@@ -49,9 +49,9 @@
}
class LoopbackInputStream extends ObjectInputStream {
- LinkedList descs;
+ LinkedList<ObjectStreamClass> descs;
- LoopbackInputStream(InputStream in, LinkedList descs) throws IOException {
+ LoopbackInputStream(InputStream in, LinkedList<ObjectStreamClass> descs) throws IOException {
super(in);
this.descs = descs;
}
@@ -59,11 +59,12 @@
protected ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException
{
- return (ObjectStreamClass) descs.removeFirst();
+ return descs.removeFirst();
}
}
public class ExternLoopback implements Externalizable {
+ private static final long serialVersionUID = 1L;
String a, b, c;
@@ -100,13 +101,17 @@
return streq(a, other.a) && streq(b, other.b) && streq(c, other.c);
}
+ public int hashCode() {
+ return a.hashCode();
+ }
+
static boolean streq(String s1, String s2) {
return (s1 != null) ? s1.equals(s2) : (s2 == null);
}
public static void main(String[] args) throws Exception {
ExternLoopback lb = new ExternLoopback("foo", "bar", "baz");
- LinkedList descs = new LinkedList();
+ LinkedList<ObjectStreamClass> descs = new LinkedList<>();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
LoopbackOutputStream lout = new LoopbackOutputStream(bout, descs);
lout.writeObject(lb);
--- a/test/jdk/java/io/Serializable/classDescHooks/Loopback.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/classDescHooks/Loopback.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -33,9 +33,9 @@
import java.util.*;
class LoopbackOutputStream extends ObjectOutputStream {
- LinkedList descs;
+ LinkedList<ObjectStreamClass> descs;
- LoopbackOutputStream(OutputStream out, LinkedList descs)
+ LoopbackOutputStream(OutputStream out, LinkedList<ObjectStreamClass> descs)
throws IOException
{
super(out);
@@ -50,21 +50,22 @@
}
class LoopbackInputStream extends ObjectInputStream {
- LinkedList descs;
+ LinkedList<ObjectStreamClass> descs;
- LoopbackInputStream(InputStream in, LinkedList descs) throws IOException {
+ LoopbackInputStream(InputStream in, LinkedList<ObjectStreamClass> descs) throws IOException {
super(in);
this.descs = descs;
}
protected ObjectStreamClass readClassDescriptor()
- throws IOException, ClassNotFoundException
{
- return (ObjectStreamClass) descs.removeFirst();
+ return descs.removeFirst();
}
}
public class Loopback implements Serializable {
+ private static final long serialVersionUID = 1L;
+
String str;
Loopback(String str) {
@@ -73,7 +74,7 @@
public static void main(String[] args) throws Exception {
Loopback lb = new Loopback("foo");
- LinkedList descs = new LinkedList();
+ LinkedList<ObjectStreamClass> descs = new LinkedList<>();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
LoopbackOutputStream lout = new LoopbackOutputStream(bout, descs);
lout.writeObject(lb);
--- a/test/jdk/java/io/Serializable/cloneArray/CloneArray.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/cloneArray/CloneArray.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 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
@@ -40,6 +40,8 @@
static Object replacement;
static class Resolver implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private Object readResolve() throws ObjectStreamException {
return replacement;
}
--- a/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,6 +30,8 @@
import java.io.*;
class Good implements Serializable {
+ private static final long serialVersionUID = 6319710844400051132L;
+
static {
try { Thread.sleep(1000); } catch (InterruptedException ex) {}
}
@@ -47,12 +49,12 @@
}
class SuccessfulLookup extends Thread {
- Class cl;
+ Class<?> cl;
long suid;
Object barrier;
boolean ok;
- SuccessfulLookup(Class cl, long suid, Object barrier) {
+ SuccessfulLookup(Class<?> cl, long suid, Object barrier) {
this.cl = cl;
this.suid = suid;
this.barrier = barrier;
@@ -72,11 +74,11 @@
}
class FailingLookup extends Thread {
- Class cl;
- Object barrier;
+ Class<?> cl;
+ final Object barrier;
boolean ok;
- FailingLookup(Class cl, Object barrier) {
+ FailingLookup(Class<?> cl, Object barrier) {
this.cl = cl;
this.barrier = barrier;
}
@@ -99,7 +101,7 @@
public class ConcurrentClassDescLookup {
public static void main(String[] args) throws Exception {
ClassLoader loader = ConcurrentClassDescLookup.class.getClassLoader();
- Class cl = Class.forName("Good", false, loader);
+ Class<?> cl = Class.forName("Good", false, loader);
Object barrier = new Object();
SuccessfulLookup[] slookups = new SuccessfulLookup[50];
for (int i = 0; i < slookups.length; i++) {
--- a/test/jdk/java/io/Serializable/defaultDataEnd/DefaultDataEnd.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/defaultDataEnd/DefaultDataEnd.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,6 +31,8 @@
import java.io.*;
class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int i1 = 1, i2 = 2;
String s1 = "foo", s2 = "bar";
@@ -66,6 +68,8 @@
}
class B implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int i1 = 1, i2 = 2;
String s1 = "foo", s2 = "bar";
@@ -101,6 +105,8 @@
}
class C implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
--- a/test/jdk/java/io/Serializable/defaultReadObjectCNFException/DefaultReadObjectCNFException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/defaultReadObjectCNFException/DefaultReadObjectCNFException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -31,6 +31,9 @@
import java.io.*;
class Foo implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
Object obj = new Bar();
private void readObject(ObjectInputStream in)
@@ -44,12 +47,14 @@
}
}
-class Bar implements Serializable {}
+class Bar implements Serializable {
+ private static final long serialVersionUID = 1L;
+}
class TestObjectInputStream extends ObjectInputStream {
TestObjectInputStream(InputStream in) throws IOException { super(in); }
- protected Class resolveClass(ObjectStreamClass desc)
+ protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
if (desc.getName().equals(Bar.class.getName())) {
--- a/test/jdk/java/io/Serializable/defaulted/GetFieldRead.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/defaulted/GetFieldRead.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -30,9 +30,9 @@
import java.io.*;
class TestClass implements Serializable {
- public static final Integer DEFAULT_OBJECT_I = new Integer(99);
+ public static final Integer DEFAULT_OBJECT_I = 99;
public static final Foo DEFAULT_OBJECT_F = new Foo();
- private static final long serialVersionUID=5748652654655279289L;
+ private static final long serialVersionUID = 5748652654655279289L;
// Fields to be serialized.
private static final ObjectStreamField[] serialPersistentFields = {
--- a/test/jdk/java/io/Serializable/defaulted/GetFieldWrite.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/defaulted/GetFieldWrite.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2003, 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
@@ -62,8 +62,7 @@
{
FileOutputStream fos = new FileOutputStream("data.ser");
ObjectOutput out = new ObjectOutputStream(fos);
- out.writeObject(new TestClass(new Foo(100, 200), new Integer(100),
- 200));
+ out.writeObject(new TestClass(new Foo(100, 200), 100, 200));
out.close();
}
};
@@ -72,6 +71,8 @@
* Test class to be used as data field
*/
class Foo implements Serializable{
+ private static final long serialVersionUID = 1L;
+
int a;
int b;
public Foo() {
--- a/test/jdk/java/io/Serializable/enum/classObject/Test.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/enum/classObject/Test.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -35,7 +35,7 @@
public static void main(String[] args) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
- Class[] classes = { Enum.class, Foo.foo.getClass(),
+ Class<?>[] classes = { Enum.class, Foo.foo.getClass(),
Foo.bar.getClass(), Foo.baz.getClass() };
for (int i = 0; i < classes.length; i++) {
oout.writeObject(classes[i]);
--- a/test/jdk/java/io/Serializable/enum/ignoreSerializationFields/Test.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/enum/ignoreSerializationFields/Test.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -34,6 +34,7 @@
foo,
bar {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final long serialVersionUID = 2L;
// bar is implemented as an inner class instance, so the following
// declaration would cause a compile-time error
@@ -42,7 +43,10 @@
// };
};
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final long serialVersionUID = 1L;
+
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("blargh", Integer.TYPE)
};
@@ -50,7 +54,7 @@
public class Test {
public static void main(String[] args) throws Exception {
- Class[] classes =
+ Class<?>[] classes =
{ Foo.class, Foo.foo.getClass(), Foo.bar.getClass() };
for (int i = 0; i < classes.length; i++) {
ObjectStreamClass desc = ObjectStreamClass.lookup(classes[i]);
--- a/test/jdk/java/io/Serializable/enum/ignoreSerializationMethods/Test.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/enum/ignoreSerializationMethods/Test.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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,14 +33,17 @@
foo,
bar {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private void writeObject(ObjectOutputStream out) throws IOException {
throw new Error("bar.writeObject invoked");
}
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
throw new Error("bar.readObject invoked");
}
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object writeReplace() throws ObjectStreamException {
throw new Error("bar.writeReplace invoked");
}
@@ -50,14 +53,17 @@
// }
};
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private void writeObject(ObjectOutputStream out) throws IOException {
throw new Error("Foo.writeObject invoked");
}
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
throw new Error("Foo.readObject invoked");
}
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
Object writeReplace() throws ObjectStreamException {
throw new Error("Foo.writeReplace invoked");
}
--- a/test/jdk/java/io/Serializable/enum/mismatchedTypecode/Test.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/enum/mismatchedTypecode/Test.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -71,7 +71,7 @@
}
oout = new TestObjectOutputStream(bout = new ByteArrayOutputStream());
- oout.writeObject(new Integer(5));
+ oout.writeObject(5);
oout.close();
oin = new ObjectInputStream(
new ByteArrayInputStream(bout.toByteArray()));
--- a/test/jdk/java/io/Serializable/evolution/AddedExternField/ReadAddedField.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/evolution/AddedExternField/ReadAddedField.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2001, 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
@@ -36,6 +36,8 @@
}
class D implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public int x;
D(int y) {
x = y;
--- a/test/jdk/java/io/Serializable/evolution/AddedExternField/WriteAddedField.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/evolution/AddedExternField/WriteAddedField.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2001, 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
@@ -36,6 +36,8 @@
import java.io.*;
class NewExternFieldClass implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
byte l;
public NewExternFieldClass() {
@@ -60,6 +62,8 @@
}
class D implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public int x;
D(int y) {
x = y;
--- a/test/jdk/java/io/Serializable/evolution/AddedField/ReadAddedField.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/evolution/AddedField/ReadAddedField.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1999, 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
@@ -33,7 +33,7 @@
import java.io.*;
class IncompatibleFieldClass implements Serializable {
- private static long serialVersionUID = 4L;
+ private static final long serialVersionUID = 3L;
int x = 5;
};
--- a/test/jdk/java/io/Serializable/evolution/AddedField/WriteAddedField.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/evolution/AddedField/WriteAddedField.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1999, 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
@@ -37,6 +37,8 @@
import java.io.*;
class NewFieldClass implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int k;
NewFieldClass(int value) {
@@ -45,11 +47,14 @@
};
class IncompatibleFieldClass implements Serializable {
- private static long serialVersionUID = 3L;
+ private static final long serialVersionUID = 3L;
int x = 5;
};
+@SuppressWarnings("serial") /* Incorrect use is being tested */
class NewExternFieldClass implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
byte l;
public NewExternFieldClass(int value) {
--- a/test/jdk/java/io/Serializable/evolution/AddedSuperClass/ReadAddedSuperClass2.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/evolution/AddedSuperClass/ReadAddedSuperClass2.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, 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
@@ -42,6 +42,8 @@
import java.io.*;
class AddedSuperClass implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// Needed at least one field to recreate failure.
int field;
}
--- a/test/jdk/java/io/Serializable/evolution/AddedSuperClass/WriteAddedSuperClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/evolution/AddedSuperClass/WriteAddedSuperClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, 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
@@ -52,6 +52,8 @@
import java.io.*;
class AddedSuperClass implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// Needed at least one field to recreate failure.
int field;
}
--- a/test/jdk/java/io/Serializable/expectedStackTrace/ExpectedStackTrace.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/expectedStackTrace/ExpectedStackTrace.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, 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
@@ -42,9 +42,11 @@
}
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested */
class SerializableObject extends NotSerializableObject
implements Serializable
{
+ private static final long serialVersionUID = 1L;
public SerializableObject(String m_str, Integer m_int) {
super(m_str, m_int);
@@ -67,7 +69,7 @@
ObjectStreamClass osc =
ObjectStreamClass.lookup(SerializableObject.class);
SerializableObject initObj =
- (SerializableObject) osc.forClass().newInstance();
+ (SerializableObject) osc.forClass().getConstructor().newInstance();
return initObj;
}
--- a/test/jdk/java/io/Serializable/explicitCNFException/ExplicitCNFException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/explicitCNFException/ExplicitCNFException.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,6 +31,8 @@
import java.io.*;
class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private void readObject(ObjectInputStream in)
throws ClassNotFoundException, IOException
{
@@ -39,6 +41,8 @@
}
class B implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
public B() {}
public void writeExternal(ObjectOutput out) throws IOException {}
--- a/test/jdk/java/io/Serializable/failureAtomicity/Bar.template Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/failureAtomicity/Bar.template Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -28,7 +28,7 @@
import failureAtomicity.SerialRef;
public class Bar extends Foo implements Serializable {
- static final long serialVersionUID = -0L;
+ private static final long serialVersionUID = -0L;
public final long barPrim;
public final String barRef;
--- a/test/jdk/java/io/Serializable/failureAtomicity/Foo.template Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/failureAtomicity/Foo.template Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -28,7 +28,7 @@
import failureAtomicity.SerialRef;
public class Foo implements Serializable {
- static final long serialVersionUID = -0L;
+ private static final long serialVersionUID = -0L;
public final int fooPrim;
public final String fooRef;
--- a/test/jdk/java/io/Serializable/failureAtomicity/SerialRef.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/failureAtomicity/SerialRef.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,9 +30,10 @@
// For verification purposes only.
public class SerialRef implements Serializable {
- static final long serialVersionUID = -0L;
+ private static final long serialVersionUID = -0L;
public static Object obj;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private final Object ref;
public SerialRef(Object ref) {
--- a/test/jdk/java/io/Serializable/fieldTypeString/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/fieldTypeString/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -42,6 +42,7 @@
class Foo implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object obj;
Foo(Object obj) {
@@ -59,7 +60,7 @@
ObjectOutputStream oout =
new ObjectOutputStream(new FileOutputStream("foo.ser"));
oout.writeObject(new Foo("foo"));
- oout.writeObject(new Foo(new Integer(0)));
+ oout.writeObject(new Foo(0));
oout.close();
oout = new ObjectOutputStream(new FileOutputStream("bar.ser"));
--- a/test/jdk/java/io/Serializable/finalFields/FinalFields.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/finalFields/FinalFields.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -29,6 +29,8 @@
import java.io.*;
class Foo implements Serializable {
+ private static final long serialVersionUID = 1L;
+
final int i;
Foo(int i) {
@@ -41,6 +43,10 @@
Foo f = (Foo) obj;
return (i == f.i);
}
+
+ public int hashCode() {
+ return i;
+ }
}
public class FinalFields {
@@ -68,4 +74,5 @@
if (! (f1.equals(f1copy) && f2.equals(f2copy)))
throw new Error("copies don't match originals");
}
+
}
--- a/test/jdk/java/io/Serializable/getSuidClinitError/GetSuidClinitError.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/getSuidClinitError/GetSuidClinitError.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,6 +30,7 @@
import java.io.*;
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class A implements Serializable {
static {
// compiler prohibits direct throw
@@ -41,30 +42,36 @@
}
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class B implements Serializable {
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class C implements Serializable {
static { System.out.println("C.<clinit>"); }
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class B1 extends B {
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class B2 extends B {
static { System.out.println("B2.<clinit>"); }
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class C1 extends C {
}
+@SuppressWarnings("serial") /* Incorrect declarations are being tested. */
class C2 extends C {
static { System.out.println("C2.<clinit>"); }
}
public class GetSuidClinitError {
public static void main(String[] args) throws Exception {
- Class cl = Class.forName(
+ Class<?> cl = Class.forName(
"A", false, GetSuidClinitError.class.getClassLoader());
for (int i = 0; i < 2; i++) {
try {
@@ -83,7 +90,7 @@
}
}
- Class[] cls = new Class[] {
+ Class<?>[] cls = {
B.class, B1.class, B2.class,
C.class, C1.class, C2.class
};
--- a/test/jdk/java/io/Serializable/lookupInterfaceDesc/LookupInterfaceDesc.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/lookupInterfaceDesc/LookupInterfaceDesc.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,10 +30,12 @@
import java.io.*;
interface Foo extends Serializable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
static final long serialVersionUID = 0xCAFE;
}
interface Bar extends Externalizable {
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
static final long serialVersionUID = 0xBABE;
}
--- a/test/jdk/java/io/Serializable/misplacedArrayClassDesc/MisplacedArrayClassDesc.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/misplacedArrayClassDesc/MisplacedArrayClassDesc.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -31,6 +31,8 @@
import java.io.*;
class TestArray implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// size of array
private static final int ARR_SIZE = 5;
// serializable field
--- a/test/jdk/java/io/Serializable/modifyStaticFields/ModifyStaticFields.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/modifyStaticFields/ModifyStaticFields.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -30,6 +30,8 @@
import java.io.*;
public class ModifyStaticFields implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[] { new ObjectStreamField("str", String.class) };
--- a/test/jdk/java/io/Serializable/nestedReplace/NestedReplace.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/nestedReplace/NestedReplace.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -35,18 +35,23 @@
import java.io.*;
class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+
Object writeReplace() throws ObjectStreamException {
return new B();
}
}
class B implements Serializable {
+ private static final long serialVersionUID = 1L;
+
Object writeReplace() throws ObjectStreamException {
return new C();
}
}
class C implements Serializable {
+ private static final long serialVersionUID = 1L;
static int writeReplaceCalled = 0;
@@ -61,6 +66,8 @@
}
class D implements Serializable {
+ private static final long serialVersionUID = 1L;
+
Object readResolve() throws ObjectStreamException {
throw new Error("readResolve() called more than once");
}
--- a/test/jdk/java/io/Serializable/noSuchFieldClarification/NoSuchFieldClarification.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/noSuchFieldClarification/NoSuchFieldClarification.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -33,8 +33,9 @@
import java.io.*;
class TwoDPoint implements Serializable {
+ private static final long serialVersionUID = 1L;
- private double radius;
+ private double radius;
private double angle;
private static final ObjectStreamField[] serialPersistentFields = {
--- a/test/jdk/java/io/Serializable/notAvailable/NotAvailable.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/notAvailable/NotAvailable.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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
@@ -76,6 +76,8 @@
}
class Class1 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int a, b;
public Class1(int aa, int bb) {
--- a/test/jdk/java/io/Serializable/oldTests/AnnotateClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/AnnotateClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, 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
@@ -102,7 +102,7 @@
/* When any class is written, add a "magic" string
* that must be verified by the TestInputStream.
*/
- protected void annotateClass(Class cl) throws IOException {
+ protected void annotateClass(Class<?> cl) throws IOException {
this.writeUTF("magic");
}
@@ -112,7 +112,6 @@
* Other objects are written as themselves.
*/
protected Object replaceObject(Object obj)
- throws IOException
{
/* For PrintStreams, like stdout and stderr, encode */
if (obj instanceof PrintStream) {
@@ -169,6 +168,7 @@
* and a small integer.
*/
class StdStream implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
private int stream = 0;
public StdStream(PrintStream s) {
--- a/test/jdk/java/io/Serializable/oldTests/ArrayTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/ArrayTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -22,6 +22,8 @@
*/
public class ArrayTest implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
byte b[] = { 0, 1};
short s[] = { 0, 1, 2};
char c[] = { 'Z', 'Y', 'X'};
--- a/test/jdk/java/io/Serializable/oldTests/ArraysOfArrays.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/ArraysOfArrays.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, 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
@@ -42,40 +42,40 @@
ostream = new FileOutputStream("piotest5.tmp");
ObjectOutputStream p = new ObjectOutputStream(ostream);
- byte b[][] = {{ 0, 1}, {2,3}};
- p.writeObject((Object)b);
+ byte[][] b = {{ 0, 1}, {2,3}};
+ p.writeObject(b);
- short s[][] = {{ 0, 1, 2}, {3,4,5}};
- p.writeObject((Object)s);
+ short[][] s = {{ 0, 1, 2}, {3,4,5}};
+ p.writeObject(s);
- char c[][] = {{ 0, 1, 2, 3}, {4, 5, 6, 7}};
- p.writeObject((Object)c);
+ char[][] c = {{ 0, 1, 2, 3}, {4, 5, 6, 7}};
+ p.writeObject(c);
- int i[][] = {{ 0, 1, 2, 3, 4}, {5, 6, 7, 8, 9}};
- p.writeObject((Object)i);
+ int[][] i = {{ 0, 1, 2, 3, 4}, {5, 6, 7, 8, 9}};
+ p.writeObject(i);
- long l[][] = {{ 0, 1, 2, 3, 4, 5}, {6,7,8,9,10,11}};
+ long[][] l = {{ 0, 1, 2, 3, 4, 5}, {6,7,8,9,10,11}};
p.writeObject((Object)l);
- boolean z[][] = new boolean[2][2];
+ boolean[][] z = new boolean[2][2];
z[0][0] = true;
z[0][1] = false;
z[1] = z[0]; // Use first row same as second
- p.writeObject((Object)z);
+ p.writeObject(z);
- float f[][] = {{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f},
+ float[][] f = {{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f},
{ 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f}};
- p.writeObject((Object)f);
+ p.writeObject(f);
- double d[][] = {{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0d},
+ double[][] d = {{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0d},
{ 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1d}};
- p.writeObject((Object)d);
+ p.writeObject(d);
- Integer Int[][] = {{ new Integer(3), new Integer(2)},
- { new Integer(1), new Integer(0)}};
- p.writeObject((Object)Int);
+ Integer Int[][] = {{ 3, 2},
+ { 1, 0}};
+ p.writeObject(Int);
p.flush();
@@ -84,12 +84,12 @@
istream = new FileInputStream("piotest5.tmp");
ObjectInputStream q = new ObjectInputStream(istream);
- byte b_u[][] = (byte [][]) (q.readObject());
+ byte[][] b_u = (byte [][]) (q.readObject());
for (int ix = 0; ix < b_u.length; ix++) {
for(int iy = 0; iy < b_u[ix].length; iy++) {
if (b[ix][iy] != b_u[ix][iy]) {
System.err.println("\nByte array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
+ ix + "][" + iy + "] expected " + b[ix][iy] +
" actual = " + b_u[ix][iy]);
throw new Error();
}
@@ -97,97 +97,97 @@
}
- short s_u[][] = (short [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ short[][] s_u = (short [][])(q.readObject());
+ for (int ix = 0; ix < s_u.length; ix++) {
+ for(int iy = 0; iy < s_u[ix].length; iy++) {
+ if (s[ix][iy] != s_u[ix][iy]) {
System.err.println("\nshort array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + s[ix][iy] +
+ " actual = " + s_u[ix][iy]);
throw new Error();
}
}
}
- char c_u[][] = (char [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ char[][] c_u = (char [][])(q.readObject());
+ for (int ix = 0; ix < c_u.length; ix++) {
+ for(int iy = 0; iy < c_u[ix].length; iy++) {
+ if (c[ix][iy] != c_u[ix][iy]) {
System.err.println("\nchar array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + c[ix][iy] +
+ " actual = " + c_u[ix][iy]);
throw new Error();
}
}
}
- int i_u[][] = (int [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ int[][] i_u = (int [][])(q.readObject());
+ for (int ix = 0; ix < i_u.length; ix++) {
+ for(int iy = 0; iy < i_u[ix].length; iy++) {
+ if (i[ix][iy] != i_u[ix][iy]) {
System.err.println("\nint array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + i[ix][iy] +
+ " actual = " + i_u[ix][iy]);
throw new Error();
}
}
}
- long l_u[][] = (long [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ long[][] l_u = (long [][])(q.readObject());
+ for (int ix = 0; ix < l_u.length; ix++) {
+ for(int iy = 0; iy < l_u[ix].length; iy++) {
+ if (l[ix][iy] != l_u[ix][iy]) {
System.err.println("\nlong array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + l[ix][iy] +
+ " actual = " + l_u[ix][iy]);
throw new Error();
}
}
}
- boolean z_u[][] = (boolean [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ boolean[][] z_u = (boolean [][])(q.readObject());
+ for (int ix = 0; ix < z_u.length; ix++) {
+ for(int iy = 0; iy < z_u[ix].length; iy++) {
+ if (z[ix][iy] != z_u[ix][iy]) {
System.err.println("\nboolean array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + z[ix][iy] +
+ " actual = " + z_u[ix][iy]);
throw new Error();
}
}
}
- float f_u[][] = (float [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ float[][] f_u = (float [][])(q.readObject());
+ for (int ix = 0; ix < f_u.length; ix++) {
+ for(int iy = 0; iy < f_u[ix].length; iy++) {
+ if (f[ix][iy] != f_u[ix][iy]) {
System.err.println("\nfloat array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + f[ix][iy] +
+ " actual = " + f_u[ix][iy]);
throw new Error();
}
}
}
- double d_u[][] = (double [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ double[][] d_u = (double [][])(q.readObject());
+ for (int ix = 0; ix < d_u.length; ix++) {
+ for(int iy = 0; iy < d_u[ix].length; iy++) {
+ if (d[ix][iy] != d_u[ix][iy]) {
System.err.println("\ndouble array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + d[ix][iy] +
+ " actual = " + d_u[ix][iy]);
throw new Error();
}
}
}
- Integer Int_u[][] = (Integer [][])(q.readObject());
- for (int ix = 0; ix < b_u.length; ix++) {
- for(int iy = 0; iy < b_u[ix].length; iy++) {
- if (b[ix][iy] != b_u[ix][iy]) {
+ Integer[][] Int_u = (Integer [][])(q.readObject());
+ for (int ix = 0; ix < Int_u.length; ix++) {
+ for(int iy = 0; iy < Int_u[ix].length; iy++) {
+ if (!Int[ix][iy].equals(Int_u[ix][iy])) {
System.err.println("\nInteger array mismatch [" +
- ix + "][" + iy + " expected " + b[ix][iy] +
- " actual = " + b_u[ix][iy]);
+ ix + "][" + iy + "] expected " + Int[ix][iy] +
+ " actual = " + Int_u[ix][iy]);
throw new Error();
}
}
--- a/test/jdk/java/io/Serializable/oldTests/BinaryTree.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/BinaryTree.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, 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,6 +75,8 @@
}
class BinaryTreeTest implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
public BinaryTreeTest left;
public BinaryTreeTest right;
public int id;
--- a/test/jdk/java/io/Serializable/oldTests/CheckForException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/CheckForException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -105,6 +105,8 @@
}
class PickleClass implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
int ii = 17;
transient int tmp[];
@@ -129,6 +131,8 @@
}
class NoPickleClass extends PickleClass {
+ private static final long serialVersionUID = 1L;
+
private void writeObject(ObjectOutputStream pw)
throws NotSerializableException
{
@@ -143,6 +147,8 @@
}
class TryPickleClass extends NoPickleClass {
+ private static final long serialVersionUID = 1L;
+
int i = 7;
transient int tmp[];
--- a/test/jdk/java/io/Serializable/oldTests/CheckingEquality.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/CheckingEquality.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -83,6 +83,8 @@
}
class Firstpsio implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
String one;
int two;
float three[];
@@ -125,6 +127,8 @@
}
class Secondpsio extends Firstpsio {
+ private static final long serialVersionUID = 1L;
+
String quatre;
int cinq;
@@ -173,6 +177,7 @@
}
class Thirdpsio extends Secondpsio {
+ private static final long serialVersionUID = 1L;
static String ign = "ignored";
transient Object oh;
@@ -184,7 +189,8 @@
static final byte dcare = (byte) 128;
private short nine = 8888;
long ten;
- java.util.Enumeration zero;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
+ java.util.Enumeration<?> zero;
boolean equals(Thirdpsio other) {
@@ -227,7 +233,7 @@
eight = (byte)8;
nine = (short)9;
ten = (long)100000;
- java.util.Enumeration em = null; /* default */
+ java.util.Enumeration<?> em = null; /* default */
super.init();
}
--- a/test/jdk/java/io/Serializable/oldTests/CircularList.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/CircularList.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, 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,6 +68,8 @@
}
class CircularListTest implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
public CircularListTest next = null;
public static CircularListTest list = null;
--- a/test/jdk/java/io/Serializable/oldTests/PrimitivesTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/PrimitivesTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -22,6 +22,8 @@
*/
public class PrimitivesTest implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
byte b = 1;
char c = 'c';
float f = 3.14159f;
--- a/test/jdk/java/io/Serializable/oldTests/ValidateClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/oldTests/ValidateClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 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
@@ -64,7 +64,7 @@
Validator vc_u;
vc_u = (Validator)q.readObject();
- if (vc_u.validated != Integer.MIN_VALUE) {
+ if (Validator.validated != Integer.MIN_VALUE) {
System.err.println("\nTEST FAILED: Validation callbacks did " +
"not complete.");
throw new Error();
@@ -80,6 +80,7 @@
}
class MissingWriterClass implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
int i = 77;
private void writeObject(ObjectOutputStream pw) throws IOException {
@@ -88,6 +89,7 @@
}
class MissingReaderClass implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
int i = 77;
private void readObject(ObjectInputStream pr) throws IOException {
@@ -97,6 +99,8 @@
class Validator implements ObjectInputValidation, java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
static int validated = Integer.MAX_VALUE; // Last value validated
int priority;
Validator next = null;
--- a/test/jdk/java/io/Serializable/optionalDataEnd/OptionalDataEnd.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/optionalDataEnd/OptionalDataEnd.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,6 +31,8 @@
import java.io.*;
class Foo implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int reps;
Foo(int reps) {
@@ -40,7 +42,7 @@
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
for (int i = 0; i < reps; i++) {
- out.writeObject(new Integer(i));
+ out.writeObject(i);
}
}
--- a/test/jdk/java/io/Serializable/packageAccess/B.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/packageAccess/B.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -29,6 +29,8 @@
*/
public class B extends A implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
public B() {
super(0);
}
--- a/test/jdk/java/io/Serializable/packageAccess/C.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/packageAccess/C.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -31,6 +31,8 @@
import java.io.*;
public class C implements Serializable {
+ private static final long serialVersionUID = 1L;
+
Object writeReplace() throws ObjectStreamException {
throw new Error("package-private writeReplace called");
}
--- a/test/jdk/java/io/Serializable/packageAccess/D.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/packageAccess/D.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -29,4 +29,5 @@
*/
public class D extends C implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
}
--- a/test/jdk/java/io/Serializable/packageAccess/PackageAccessTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/packageAccess/PackageAccessTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -50,8 +50,8 @@
public class PackageAccessTest {
- static Class bcl;
- static Class dcl;
+ static Class<?> bcl;
+ static Class<?> dcl;
public static void main(String[] args) throws Exception {
setup();
@@ -62,7 +62,7 @@
bcl = Class.forName("B", true, ldr);
dcl = Class.forName("D", true, ldr);
- Object b = bcl.newInstance();
+ Object b = bcl.getConstructor().newInstance();
try {
swizzle(b);
throw new Error("expected InvalidClassException for class B");
@@ -74,7 +74,7 @@
throw new Error("package private constructor of A invoked");
}
- Object d = dcl.newInstance();
+ Object d = dcl.getConstructor().newInstance();
swizzle(d);
}
}
@@ -103,7 +103,7 @@
super(in);
}
- protected Class resolveClass(ObjectStreamClass desc)
+ protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String n = desc.getName();
--- a/test/jdk/java/io/Serializable/parents/EvolvedClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/parents/EvolvedClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, 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
@@ -52,6 +52,8 @@
* must not be invoked.
*/
class ASuperClass implements Serializable {
+ private static final long serialVersionUID = 1L;
+
String name;
ASuperClass() {
--- a/test/jdk/java/io/Serializable/parents/OriginalClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/parents/OriginalClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, 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
@@ -59,6 +59,8 @@
class ASubClass implements Serializable {
+ private static final long serialVersionUID = 6341246181948372513L;
+
int num;
ASubClass(int num) {
--- a/test/jdk/java/io/Serializable/partialClassDesc/PartialClassDesc.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/partialClassDesc/PartialClassDesc.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -43,7 +43,7 @@
public class PartialClassDesc {
public static void main(String[] args) throws Exception {
- Class cl = Class.forName(
+ Class<?> cl = Class.forName(
"A", false, PartialClassDesc.class.getClassLoader());
ObjectStreamClass desc = null;
try {
--- a/test/jdk/java/io/Serializable/primitiveClasses/PrimitiveClasses.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/primitiveClasses/PrimitiveClasses.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2002, 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
@@ -30,7 +30,7 @@
public class PrimitiveClasses {
public static void main(String[] args) throws Exception {
- Class[] primClasses = new Class[] {
+ Class<?>[] primClasses = {
boolean.class, byte.class, char.class, short.class,
int.class, long.class, float.class, double.class, void.class
};
--- a/test/jdk/java/io/Serializable/proxy/Basic.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/proxy/Basic.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, 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
@@ -36,12 +36,13 @@
// dummy invocation handler
class Handler implements InvocationHandler, Serializable {
+ private static final long serialVersionUID = 1L;
static Method fooMethod, barMethod;
static {
try {
- fooMethod = Foo.class.getDeclaredMethod("foo", new Class[0]);
- barMethod = Bar.class.getDeclaredMethod("bar", new Class[0]);
+ fooMethod = Foo.class.getDeclaredMethod("foo", new Class<?>[0]);
+ barMethod = Bar.class.getDeclaredMethod("bar", new Class<?>[0]);
} catch (NoSuchMethodException ex) {
throw new Error();
}
@@ -59,9 +60,9 @@
throws Throwable
{
if (method.equals(fooMethod)) {
- return new Integer(foo);
+ return foo;
} else if (method.equals(barMethod)) {
- return new Float(bar);
+ return bar;
} else {
throw new UnsupportedOperationException();
}
@@ -73,7 +74,7 @@
ProxyBlindInputStream(InputStream in) throws IOException { super(in); }
- protected Class resolveProxyClass(String[] interfaces)
+ protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException
{
throw new ClassNotFoundException();
@@ -83,7 +84,7 @@
public class Basic {
public static void main(String[] args) throws Exception {
ClassLoader loader = Basic.class.getClassLoader();
- Class[] interfaces = new Class[] { Foo.class, Bar.class };
+ Class<?>[] interfaces = { Foo.class, Bar.class };
Random rand = new Random();
int foo = rand.nextInt();
float bar = rand.nextFloat();
--- a/test/jdk/java/io/Serializable/proxy/replace/Test.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/proxy/replace/Test.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,6 +30,7 @@
import java.lang.reflect.*;
public class Test implements InvocationHandler, Serializable {
+ private static final long serialVersionUID = 1L;
static ClassLoader loader = Test.class.getClassLoader();
@@ -39,10 +40,10 @@
String methName = method.getName();
if (methName.equals("writeReplace")) {
return Proxy.newProxyInstance(
- loader, new Class[] { ReadResolve.class }, this);
+ loader, new Class<?>[] { ReadResolve.class }, this);
} else if (methName.equals("readResolve")) {
return Proxy.newProxyInstance(
- loader, new Class[] { Resolved.class }, this);
+ loader, new Class<?>[] { Resolved.class }, this);
} else if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
} else {
@@ -54,7 +55,7 @@
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(Proxy.newProxyInstance(
- loader, new Class[] { WriteReplace.class }, new Test()));
+ loader, new Class<?>[] { WriteReplace.class }, new Test()));
oout.close();
ObjectInputStream oin = new ObjectInputStream(
new ByteArrayInputStream(bout.toByteArray()));
--- a/test/jdk/java/io/Serializable/proxy/skipMissing/Handler.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/proxy/skipMissing/Handler.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -30,6 +30,8 @@
import java.lang.reflect.*;
class Handler implements InvocationHandler, Serializable {
+ private static final long serialVersionUID = 1L;
+
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
--- a/test/jdk/java/io/Serializable/proxy/skipMissing/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/proxy/skipMissing/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, 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
@@ -42,6 +42,7 @@
class A implements Serializable {
private static final long serialVersionUID = 0L;
String a = "a";
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object proxy;
String z = "z";
@@ -65,7 +66,7 @@
public static void main(String[] args) throws Exception {
Object proxy = Proxy.newProxyInstance(
Write.class.getClassLoader(),
- new Class[] { I.class }, new Handler());
+ new Class<?>[] { I.class }, new Handler());
ObjectOutputStream oout = new ObjectOutputStream(
new FileOutputStream("tmp.ser"));
oout.writeObject(new A(proxy));
--- a/test/jdk/java/io/Serializable/readObjectNoData/Read.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/readObjectNoData/Read.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, 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
@@ -48,6 +48,7 @@
class B extends A implements Serializable {
private static final long serialVersionUID = 0L;
boolean bCalled = false;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private void readObjectNoData(int wrong) throws ObjectStreamException {
bCalled = true;
}
@@ -82,6 +83,7 @@
class E extends D {
private static final long serialVersionUID = 0L;
boolean eCalled = false;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
void readObjectNoData() throws ObjectStreamException {
eCalled = true;
}
--- a/test/jdk/java/io/Serializable/recursiveClassDescLookup/Test.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/recursiveClassDescLookup/Test.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -40,7 +40,7 @@
public class Test {
public static void main(String[] args) throws Exception {
- Class fooCl = Class.forName("Foo", false, Test.class.getClassLoader());
+ Class<?> fooCl = Class.forName("Foo", false, Test.class.getClassLoader());
ObjectStreamClass.lookup(fooCl);
System.out.println("done.");
}
--- a/test/jdk/java/io/Serializable/replaceStringArray/ReplaceStringArray.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/replaceStringArray/ReplaceStringArray.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, 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,6 +30,8 @@
import java.lang.reflect.Array;
class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+
String stringA;
String stringB;
String stringC;
@@ -74,7 +76,7 @@
Object[] array = (Object[]) obj;
/* Double the array.
* Initialize new array elements with original array. */
- Class arrayComponentType = array.getClass().getComponentType();
+ Class<?> arrayComponentType = array.getClass().getComponentType();
Object[] newarray =
(Object[])Array.newInstance(arrayComponentType,
array.length * 2);
@@ -108,7 +110,7 @@
/* Double the array.
* Initialize new array elements with original array. */
- Class arrayComponentType = array.getClass().getComponentType();
+ Class<?> arrayComponentType = array.getClass().getComponentType();
Object[] newarray =
(Object[])Array.newInstance(arrayComponentType,
array.length * 2);
--- a/test/jdk/java/io/Serializable/resolveClass/MethodTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/resolveClass/MethodTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,9 +31,11 @@
import java.lang.reflect.*;
public class MethodTest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public static void main(String[] args) throws Exception {
Method readObject = ObjectInputStream.class.getDeclaredMethod(
- "readObject", new Class[0]);
+ "readObject", new Class<?>[0]);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(new MethodTest());
--- a/test/jdk/java/io/Serializable/resolveClass/consTest/ConsTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/resolveClass/consTest/ConsTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -42,9 +42,10 @@
import jdk.test.lib.util.JarUtils;
public class ConsTest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public static void main(String[] args) throws Exception {
- Constructor cons = Boot.class.getConstructor(
- new Class[] { ObjectInputStream.class });
+ Constructor<?> cons = Boot.class.getConstructor(ObjectInputStream.class);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(new ConsTest());
@@ -53,7 +54,7 @@
for (int i = 0; i < 100; i++) {
ObjectInputStream oin = new ObjectInputStream(
new ByteArrayInputStream(bout.toByteArray()));
- cons.newInstance(new Object[]{ oin });
+ cons.newInstance(oin);
}
}
}
--- a/test/jdk/java/io/Serializable/resolveClass/deserializeButton/DeserializeButtonTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/resolveClass/deserializeButton/DeserializeButtonTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -46,7 +46,8 @@
try (URLClassLoader ldr =
new URLClassLoader(new URL[]{ new URL("file:cb.jar") })) {
- Runnable r = (Runnable) Class.forName("Foo", true, ldr).newInstance();
+ Runnable r = (Runnable) Class.forName("Foo", true, ldr)
+ .getConstructor().newInstance();
r.run();
}
}
--- a/test/jdk/java/io/Serializable/resolveClass/deserializeButton/Foo.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/resolveClass/deserializeButton/Foo.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, 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
@@ -34,7 +34,9 @@
public class Foo implements Runnable {
- static class TestElement extends Object implements Serializable {}
+ static class TestElement extends Object implements Serializable {
+ private static final long serialVersionUID = 1L;
+ }
public void run() {
try {
--- a/test/jdk/java/io/Serializable/resolveClassException/ResolveClassException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/resolveClassException/ResolveClassException.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -37,8 +37,8 @@
super(in);
}
- protected Class resolveClass(ObjectStreamClass desc)
- throws IOException, ClassNotFoundException
+ protected Class<?> resolveClass(ObjectStreamClass desc)
+ throws ClassNotFoundException
{
throw new ClassNotFoundException(message);
}
@@ -53,7 +53,7 @@
Object obj;
// write and read an object
- obj = new Integer(5);
+ obj = 5;
bout = new ByteArrayOutputStream();
oout = new ObjectOutputStream(bout);
oout.writeObject(obj);
@@ -67,7 +67,7 @@
}
// write and read an array of objects
- obj = new Integer[] { new Integer(5) };
+ obj = new Integer[] { 5 };
bout = new ByteArrayOutputStream();
oout = new ObjectOutputStream(bout);
oout.writeObject(obj);
--- a/test/jdk/java/io/Serializable/resolveProxyClass/NonPublicInterface.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/resolveProxyClass/NonPublicInterface.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, 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
@@ -37,6 +37,8 @@
public class NonPublicInterface {
static class Handler implements InvocationHandler, Serializable {
+ private static final long serialVersionUID = 1L;
+
public Object invoke(Object obj, Method meth, Object[] args) {
return null;
}
--- a/test/jdk/java/io/Serializable/sanityCheck/SanityCheck.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/sanityCheck/SanityCheck.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -31,6 +31,7 @@
import java.util.*;
class Item implements Serializable {
+ private static final long serialVersionUID = 1L;
static final int ARRAYLEN = 1000;
static final int STRLEN = 1000;
@@ -55,6 +56,7 @@
double[] dary;
String str;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object[] oary;
Item() {
@@ -86,7 +88,7 @@
fary[i] = rand.nextFloat();
jary[i] = rand.nextLong();
dary[i] = rand.nextDouble();
- oary[i] = new Integer(rand.nextInt());
+ oary[i] = rand.nextInt();
}
char[] strChars = new char[STRLEN];
@@ -126,6 +128,11 @@
return true;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(i, j);
+ }
}
public class SanityCheck {
--- a/test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -730,6 +730,7 @@
static class ReadResolveToArray implements Serializable, ObjectInputFilter {
private static final long serialVersionUID = 123456789L;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
private final Object array;
private final int length;
--- a/test/jdk/java/io/Serializable/serialver/classpath/ClasspathTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/serialver/classpath/ClasspathTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, 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
@@ -44,6 +44,7 @@
import jdk.test.lib.process.ProcessTools;
public class ClasspathTest implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
int a;
int b;
--- a/test/jdk/java/io/Serializable/serialver/nested/NestedTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/serialver/nested/NestedTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, 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,11 @@
import jdk.test.lib.process.ProcessTools;
public class NestedTest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public static class Test1 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public static class Test2 implements Serializable{
private static final long serialVersionUID = 100L;
}
--- a/test/jdk/java/io/Serializable/skipToEndOfBlockData/SkipToEndOfBlockData.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/skipToEndOfBlockData/SkipToEndOfBlockData.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -32,6 +32,8 @@
import java.io.*;
class MismatchedRead implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int i;
float f;
@@ -59,9 +61,15 @@
MismatchedRead other = (MismatchedRead) obj;
return (i == other.i && f == other.f);
}
+
+ public int hashCode() {
+ return i;
+ }
}
class MismatchedReadExternal implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
int i;
float f;
@@ -91,9 +99,15 @@
MismatchedReadExternal other = (MismatchedReadExternal) obj;
return (i == other.i && f == other.f);
}
+
+ public int hashCode() {
+ return i;
+ }
}
class InnocentBystander implements Serializable {
+ private static final long serialVersionUID = 1L;
+
String s;
InnocentBystander(String s) {
@@ -108,6 +122,10 @@
return s.equals(other.s);
return (s == other.s);
}
+
+ public int hashCode() {
+ return s.hashCode();
+ }
}
public class SkipToEndOfBlockData {
--- a/test/jdk/java/io/Serializable/skipWriteObject/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/skipWriteObject/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -44,6 +44,8 @@
}
class Bar implements Serializable {
+ private static final long serialVersionUID = 1L;
+
int a, b;
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
--- a/test/jdk/java/io/Serializable/skippedObjCNFException/Read.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/skippedObjCNFException/Read.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, 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
@@ -37,6 +37,7 @@
class B implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object c;
}
--- a/test/jdk/java/io/Serializable/skippedObjCNFException/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/skippedObjCNFException/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -43,11 +43,13 @@
// all three following fields not present on reading side
B b = new B();
C c = new C();
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object ca = new Object[] { new C() };
}
class B implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object c = new C();
}
--- a/test/jdk/java/io/Serializable/stopCustomDeserialization/Read.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/stopCustomDeserialization/Read.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, 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
@@ -32,6 +32,7 @@
class A implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object x;
}
--- a/test/jdk/java/io/Serializable/stopCustomDeserialization/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/stopCustomDeserialization/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -39,6 +39,7 @@
class A implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("serial") /* Incorrect declarations are being tested */
Object x = new X();
}
--- a/test/jdk/java/io/Serializable/subclass/AbstractObjectInputStream.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/subclass/AbstractObjectInputStream.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2004, 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
@@ -253,7 +253,7 @@
* @exception InstantiationException TBD.
*/
protected final native Object
- allocateNewObject(Class ofClass, Class ctorClass)
+ allocateNewObject(Class<?> ofClass, Class<?> ctorClass)
throws InstantiationException, IllegalAccessException;
/**
@@ -271,7 +271,7 @@
* @exception InstantiationException TBD.
*/
protected final native Object
- allocateNewArray(Class componentClass, int length)
+ allocateNewArray(Class<?> componentClass, int length)
throws InstantiationException, IllegalAccessException;
/**
@@ -317,5 +317,6 @@
public abstract int skipBytes(int len) throws IOException;
/* @deprecated */
+ @SuppressWarnings("deprecation")
public abstract String readLine() throws IOException;
};
--- a/test/jdk/java/io/Serializable/subclass/SubclassTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/subclass/SubclassTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, 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
@@ -57,6 +57,8 @@
* Test if customized readObject and writeObject are called.
*/
class B implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public int publicIntField;
public static int numWriteObjectCalled = 0;
B(int v) {
@@ -80,9 +82,11 @@
*/
class C implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public int xx1;
public int xx2;
- static final ObjectStreamField[] serialPersistentFields = {
+ private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("x1", Integer.TYPE),
new ObjectStreamField("x2", Integer.TYPE),
new ObjectStreamField("x3", Integer.TYPE),
@@ -106,6 +110,8 @@
class A implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public int publicIntField;
public long publicLongField;
public B publicBField;
--- a/test/jdk/java/io/Serializable/subclass/XObjectInputStream.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/subclass/XObjectInputStream.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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,7 @@
Object readResult = null;
Object prevObject = currentObject;
- Class prevDesc = currentClassDescriptor;
+ Class<?> prevDesc = currentClassDescriptor;
boolean NotImplemented = true;
if (NotImplemented)
@@ -243,7 +243,7 @@
}
private Object currentObject;
- private Class currentClassDescriptor;
+ private Class<?> currentClassDescriptor;
@@ -256,15 +256,15 @@
* Set the accessible flag on it here. ObjectOutputStream
* will call it as necessary.
*/
- public static Method getReadObjectMethod(final Class cl) {
+ public static Method getReadObjectMethod(final Class<?> cl) {
- Method readObjectMethod = (Method)
+ Method readObjectMethod =
java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction() {
- public Object run() {
+ (new java.security.PrivilegedAction<Method>() {
+ public Method run() {
Method m = null;
try {
- Class[] args = {ObjectInputStream.class};
+ Class<?>[] args = {ObjectInputStream.class};
m = cl.getDeclaredMethod("readObject", args);
int mods = m.getModifiers();
// Method must be private and non-static
@@ -292,8 +292,8 @@
{
try {
java.security.AccessController.doPrivileged
- (new java.security.PrivilegedExceptionAction() {
- public Object run() throws InvocationTargetException,
+ (new java.security.PrivilegedExceptionAction<Void>() {
+ public Void run() throws InvocationTargetException,
java.lang.IllegalAccessException {
m.invoke(obj, argList);
return null;
--- a/test/jdk/java/io/Serializable/subclass/XObjectOutputStream.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/subclass/XObjectOutputStream.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2004, 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
@@ -116,7 +116,7 @@
int mods = fields[i].getModifiers();
if (Modifier.isStatic(mods) || Modifier.isTransient(mods))
continue;
- Class FieldType = fields[i].getType();
+ Class<?> FieldType = fields[i].getType();
if (FieldType.isPrimitive()) {
System.out.println("Field " + fields[i].getName() +
" has primitive type " + FieldType.toString());
@@ -127,7 +127,7 @@
writeObject(fields[i].get(obj));
if (FieldType.isArray()) {
Object[] array = ((Object[]) fields[i].get(obj));
- Class componentType = FieldType.getComponentType();
+ Class<?> componentType = FieldType.getComponentType();
if (componentType.isPrimitive())
System.out.println("Output " + array.length + " primitive elements of" +
componentType.toString());
@@ -227,6 +227,7 @@
/**
* Write the data and fields to the specified ObjectOutput stream.
*/
+ @SuppressWarnings("deprecation")
public void write(ObjectOutput out) throws IOException {
for (int i = 0; i < next; i++)
System.out.println(fieldName[i] + "=" + intValue[i]);
@@ -300,15 +301,15 @@
* Set the accessible flag on it here.
* Subclass of AbstractObjectOutputStream will call it as necessary.
*/
- public static Method getWriteObjectMethod(final Class cl) {
+ public static Method getWriteObjectMethod(final Class<?> cl) {
- Method writeObjectMethod = (Method)
+ Method writeObjectMethod =
java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction() {
- public Object run() {
+ (new java.security.PrivilegedAction<Method>() {
+ public Method run() {
Method m = null;
try {
- Class[] args = {ObjectOutputStream.class};
+ Class<?>[] args = {ObjectOutputStream.class};
m = cl.getDeclaredMethod("writeObject", args);
int mods = m.getModifiers();
// Method must be private and non-static
@@ -336,8 +337,8 @@
{
try {
java.security.AccessController.doPrivileged
- (new java.security.PrivilegedExceptionAction() {
- public Object run() throws InvocationTargetException,
+ (new java.security.PrivilegedExceptionAction<Void>() {
+ public Void run() throws InvocationTargetException,
java.lang.IllegalAccessException {
m.invoke(obj, argList);
return null;
--- a/test/jdk/java/io/Serializable/superclassDataLoss/A.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/superclassDataLoss/A.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -29,6 +29,8 @@
*/
public class A implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
protected final int i;
protected A(int i) { this.i = i; }
}
--- a/test/jdk/java/io/Serializable/superclassDataLoss/B.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/superclassDataLoss/B.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -29,6 +29,8 @@
*/
public class B extends A implements Runnable {
+ private static final long serialVersionUID = 1L;
+
public B() { super(0xDEADBEEF); }
// verify superclass data still present
--- a/test/jdk/java/io/Serializable/superclassDataLoss/SuperclassDataLossTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/superclassDataLoss/SuperclassDataLossTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, 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
@@ -62,7 +62,7 @@
this.ldr12A = ldr12A;
}
- protected Class resolveClass(ObjectStreamClass desc)
+ protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
// resolve A's classdesc to class != B's superclass
@@ -91,7 +91,8 @@
URLClassLoader ldr2 = new URLClassLoader(new URL[] { new URL("file:cb2.jar") })) {
setup();
- Runnable a = (Runnable) Class.forName("B", true, ldr1).newInstance();
+ Runnable a = (Runnable) Class.forName("B", true, ldr1)
+ .getConstructor().newInstance();
a.run();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
--- a/test/jdk/java/io/Serializable/survivePrematureClose/SurvivePrematureClose.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/survivePrematureClose/SurvivePrematureClose.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -32,6 +32,7 @@
import java.io.*;
class A implements Externalizable {
+ private static final long serialVersionUID = 1L;
public A() {}
@@ -49,6 +50,7 @@
}
class B implements Serializable {
+ private static final long serialVersionUID = 1L;
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
--- a/test/jdk/java/io/Serializable/typeSafeEnum/TypeSafeEnum.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/typeSafeEnum/TypeSafeEnum.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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,6 +30,8 @@
import java.io.*;
public class TypeSafeEnum implements Serializable, ObjectInputValidation {
+ private static final long serialVersionUID = 1L;
+
private static int numWriteObject = 0;
private static int numReadObject = 0;
@@ -47,7 +49,7 @@
static boolean verbose = false;
- private Object writeReplace() throws IOException {
+ private Object writeReplace() {
numWriteReplace++;
if (verbose) {
System.out.println("TypeSafeEnum.writeReplace() " +
@@ -56,7 +58,7 @@
return this;
}
- private Object readResolve() throws IOException {
+ private Object readResolve() {
numReadResolve++;
if (verbose) {
System.out.println("readResolve called on " + this.toString());
--- a/test/jdk/java/io/Serializable/typeStringBackRef/TypeStringBackRef.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/typeStringBackRef/TypeStringBackRef.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,6 +30,7 @@
import java.io.*;
public class TypeStringBackRef implements Serializable {
+ private static final long serialVersionUID = 1L;
String a, b, c, d, e, f, g;
--- a/test/jdk/java/io/Serializable/underlyingOutputStreamException/UnderlyingOutputStreamException.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/underlyingOutputStreamException/UnderlyingOutputStreamException.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -30,6 +30,7 @@
import java.io.*;
class OriginalIOException extends IOException {
+ private static final long serialVersionUID = 1L;
}
class BrokenOutputStream extends OutputStream {
--- a/test/jdk/java/io/Serializable/unnamedPackageSwitch/UnnamedPackageSwitchTest.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/unnamedPackageSwitch/UnnamedPackageSwitchTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, 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
@@ -46,7 +46,7 @@
class TestObjectInputStream extends ObjectInputStream {
TestObjectInputStream(InputStream in) throws IOException { super(in); }
- protected Class resolveClass(ObjectStreamClass desc)
+ protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String name = desc.getName();
--- a/test/jdk/java/io/Serializable/unresolvableObjectStreamClass/UnresolvableObjectStreamClass.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/unresolvableObjectStreamClass/UnresolvableObjectStreamClass.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -65,4 +65,5 @@
}
class MySerializable implements Serializable {
+ private static final long serialVersionUID = 1L;
}
--- a/test/jdk/java/io/Serializable/unresolvedClassDesc/Foo.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/unresolvedClassDesc/Foo.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -29,4 +29,5 @@
*/
public class Foo implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
}
--- a/test/jdk/java/io/Serializable/unshared/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/unshared/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -37,6 +37,8 @@
import java.io.*;
class Foo implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[] {
new ObjectStreamField("shared1", String.class),
@@ -54,6 +56,7 @@
class Bar implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
Object obj;
Bar(Object obj) {
--- a/test/jdk/java/io/Serializable/userRWObjError/UserRWObjError.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/userRWObjError/UserRWObjError.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 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
@@ -39,6 +39,7 @@
*/
public class UserRWObjError implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
public static void main(String[] args) throws Exception {
try {
--- a/test/jdk/java/io/Serializable/validate/Validate.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/validate/Validate.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 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
@@ -73,6 +73,8 @@
}
class Class1 implements Serializable, ObjectInputValidation {
+ private static final long serialVersionUID = 1L;
+
int a, b;
transient int validates;
--- a/test/jdk/java/io/Serializable/verifyDynamicObjHandleTable/VerifyDynamicObjHandleTable.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/verifyDynamicObjHandleTable/VerifyDynamicObjHandleTable.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, 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
@@ -31,7 +31,9 @@
import java.util.Iterator;
class A implements Serializable {
- static HashSet writeObjectExtent = new HashSet();
+ private static final long serialVersionUID = 1L;
+
+ static HashSet<A> writeObjectExtent = new HashSet<>();
private void writeObject(ObjectOutputStream out) throws IOException {
if (writeObjectExtent.contains(this)) {
@@ -63,7 +65,7 @@
// allow writeObject to be called on any objects that
// have already been serialized. These objects should be
// written out by reference.
- Iterator iter = A.writeObjectExtent.iterator();
+ Iterator<A> iter = A.writeObjectExtent.iterator();
while (iter.hasNext()) {
out.writeObject(iter.next());
}
--- a/test/jdk/java/io/Serializable/writeObjectMemory/WriteObjectMemory.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/writeObjectMemory/WriteObjectMemory.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2004, 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
@@ -33,7 +33,9 @@
import java.util.Iterator;
class A implements Serializable {
- static HashSet writeObjectExtent = new HashSet();
+ private static final long serialVersionUID = 1L;
+
+ static HashSet<A>writeObjectExtent = new HashSet<>();
private void writeObject(ObjectOutputStream out) throws IOException {
if (writeObjectExtent.contains(this)) {
@@ -53,7 +55,7 @@
public class WriteObjectMemory {
public static void main(String args[])
- throws IOException, ClassNotFoundException
+ throws IOException
{
ObjectOutputStream out =
new ObjectOutputStream(new ByteArrayOutputStream(3000));
@@ -65,7 +67,7 @@
// allow writeObject to be called on any objects that
// have already been serialized. These objects should be
// written out by reference.
- Iterator iter = A.writeObjectExtent.iterator();
+ Iterator<A> iter = A.writeObjectExtent.iterator();
while (iter.hasNext()) {
out.writeObject(iter.next());
}
--- a/test/jdk/java/io/Serializable/writeReplace/WriteReplace.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/writeReplace/WriteReplace.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 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
@@ -30,6 +30,9 @@
public class WriteReplace {
static class ReplaceMe implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private Object obj;
private boolean writeReplaceCalled = false;
--- a/test/jdk/java/io/Serializable/wrongReturnTypes/Read.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/wrongReturnTypes/Read.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, 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
@@ -34,6 +34,7 @@
static boolean readObjectNoDataCalled;
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private Object readObjectNoData() throws ObjectStreamException {
readObjectNoDataCalled = true;
return null;
@@ -46,6 +47,7 @@
static boolean readObjectCalled;
static boolean readResolveCalled;
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private Integer readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
@@ -54,6 +56,7 @@
return null;
}
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private B readResolve() throws ObjectStreamException {
readResolveCalled = true;
return this;
--- a/test/jdk/java/io/Serializable/wrongReturnTypes/Write.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/io/Serializable/wrongReturnTypes/Write.java Wed Oct 16 11:23:46 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -43,12 +43,14 @@
static boolean writeObjectCalled;
static boolean writeReplaceCalled;
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private Object writeObject(ObjectOutputStream out) throws IOException {
writeObjectCalled = true;
out.defaultWriteObject();
return null;
}
+ @SuppressWarnings("serial") /* Incorrect use is being tested */
private B writeReplace() throws ObjectStreamException {
writeReplaceCalled = true;
return this;
--- a/test/jdk/java/lang/ProcessBuilder/Basic.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/lang/ProcessBuilder/Basic.java Wed Oct 16 11:23:46 2019 +0200
@@ -2111,6 +2111,19 @@
case 2: r = s.read(bytes); break;
default: throw new Error();
}
+ if (r >= 0) {
+ // The child sent unexpected output; print it to diagnose
+ System.out.println("Unexpected child output:");
+ if ((action & 0x2) == 0) {
+ System.out.write(r); // Single character
+
+ } else {
+ System.out.write(bytes, 0, r);
+ }
+ for (int c = s.read(); c >= 0; c = s.read())
+ System.out.write(c);
+ System.out.println("\nEND Child output.");
+ }
equal(-1, r);
} catch (IOException ioe) {
if (!ioe.getMessage().equals("Stream closed")) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Runtime/loadLibrary/LoadLibraryTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8231584
+ * @library /test/lib
+ * @run main/othervm LoadLibraryTest
+ */
+
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.net.MalformedURLException;
+import java.net.URLClassLoader;
+import java.net.URL;
+
+import jdk.test.lib.compiler.CompilerUtils;
+
+public class LoadLibraryTest {
+ static Thread thread1 = null;
+ static Thread thread2 = null;
+
+ static volatile boolean thread1Ready = false;
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+ private static final Path CLS_DIR = Paths.get("classes");
+
+ static TestClassLoader loader;
+ static void someLibLoad() {
+ try {
+/*
+ FileSystems.getDefault();
+
+ // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime)
+ java.net.NetworkInterface.getNetworkInterfaces();
+
+ System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
+*/
+ Class c = Class.forName("Target2", true, loader);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static class TestClassLoader extends URLClassLoader {
+ boolean passed = false;
+
+ public boolean passed() {
+ return passed;
+ }
+
+ TestClassLoader() throws MalformedURLException {
+ super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') });
+ }
+
+ public String findLibrary(String name) {
+ System.out.println("findLibrary " + name);
+
+ if ("someLibrary".equals(name)) {
+ try {
+ synchronized(thread1) {
+ while(!thread1Ready) {
+ thread1.wait();
+ }
+ thread1.notifyAll();
+ }
+
+ Thread.sleep(10000);
+
+ System.out.println("Thread2 load");
+ someLibLoad();
+
+ // no deadlock happened
+ passed = true;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+
+ return super.findLibrary(name);
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ loader = new TestClassLoader();
+
+ if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) {
+ throw new Exception("Can't compile");
+ }
+
+ thread1 = new Thread() {
+ public void run() {
+ try {
+ synchronized(this) {
+ thread1Ready = true;
+ thread1.notifyAll();
+ thread1.wait();
+ }
+ } catch(InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ System.out.println("Thread1 load");
+ someLibLoad();
+ };
+ };
+
+ thread2 = new Thread() {
+ public void run() {
+ try {
+ Class c = Class.forName("Target", true, loader);
+ System.out.println(c);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ };
+ };
+
+ thread1.setDaemon(true);
+ thread2.setDaemon(true);
+
+ thread1.start();
+ thread2.start();
+
+ thread1.join();
+ thread2.join();
+
+ if (!loader.passed()) {
+ throw new RuntimeException("FAIL");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Runtime/loadLibrary/src/Target.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+class Target {
+ static {
+ try {
+ System.loadLibrary("someLibrary");
+ throw new RuntimeException("someLibrary was loaded");
+ } catch (UnsatisfiedLinkError e) {
+ // expected: we do not have a someLibrary
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Runtime/loadLibrary/src/Target2.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+class Target2 {
+ static {
+ System.loadLibrary("awt");
+ }
+}
+
--- a/test/jdk/java/rmi/testlibrary/TestSocketFactory.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/rmi/testlibrary/TestSocketFactory.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -92,7 +92,8 @@
static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
- public static final boolean DEBUG = false;
+ // True to enable logging of matches and replacements.
+ private static volatile boolean debugLogging = false;
/**
* Debugging output can be synchronized with logging of RMI actions.
@@ -100,8 +101,8 @@
* @param format a printf format
* @param args any args
*/
- private static void DEBUG(String format, Object... args) {
- if (DEBUG) {
+ public static void DEBUG(String format, Object... args) {
+ if (debugLogging) {
System.err.printf(format, args);
}
}
@@ -117,6 +118,17 @@
}
/**
+ * Set debug to true to generate logging output of matches and substitutions.
+ * @param debug {@code true} to generate logging output
+ * @return the previous value
+ */
+ public static boolean setDebug(boolean debug) {
+ boolean oldDebug = debugLogging;
+ debugLogging = debug;
+ return oldDebug;
+ }
+
+ /**
* Set the match and replacement bytes, with an empty trigger.
* The match and replacements are propagated to all existing sockets.
*
--- a/test/jdk/java/security/testlibrary/Proc.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/security/testlibrary/Proc.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -25,6 +25,9 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -110,6 +113,7 @@
private List<String> args = new ArrayList<>();
private Map<String,String> env = new HashMap<>();
private Map<String,String> prop = new HashMap();
+ private Map<String,String> secprop = new HashMap();
private boolean inheritIO = false;
private boolean noDump = false;
@@ -176,6 +180,11 @@
prop.put(a, b);
return this;
}
+ // Specifies a security property. Can be called multiple times.
+ public Proc secprop(String a, String b) {
+ secprop.put(a, b);
+ return this;
+ }
// Inherit the value of a system property
public Proc inheritProp(String k) {
String v = System.getProperty(k);
@@ -282,6 +291,17 @@
cmd.add(cp.stream().collect(Collectors.joining(File.pathSeparator)));
}
+ if (!secprop.isEmpty()) {
+ Path p = Path.of(getId("security"));
+ try (OutputStream fos = Files.newOutputStream(p);
+ PrintStream ps = new PrintStream(fos)) {
+ secprop.forEach((k,v) -> ps.println(k + "=" + v));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ prop.put("java.security.properties", p.toString());
+ }
+
for (Entry<String,String> e: prop.entrySet()) {
cmd.add("-D" + e.getKey() + "=" + e.getValue());
}
@@ -380,6 +400,12 @@
}
return p.waitFor();
}
+ // Wait for process end with expected exit code
+ public void waitFor(int expected) throws Exception {
+ if (p.waitFor() != expected) {
+ throw new RuntimeException("Exit code not " + expected);
+ }
+ }
// The following methods are used inside a proc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Format/DateFormat/SimpleDateFormatPatternTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -0,0 +1,229 @@
+/*
+ * 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 4326988 6990146 8231213
+ * @summary test SimpleDateFormat, check its pattern in the constructor
+ * @run testng/othervm SimpleDateFormatPatternTest
+ */
+import java.lang.IllegalArgumentException;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class SimpleDateFormatPatternTest {
+ private static String[] validPat = {
+ "yyyy-MM-dd h.mm.ss.a z",
+ "yyyy'M'd' ahh'mm'ss' z",
+ "dd MMMM yyyy hh:mm:ss",
+ "d MMM yy HH:mm:ss",
+ "dd/MM/yyyy HH:mm:ss",
+ "d' / 'MMMM' / 'yyyy HH:mm:ss z",
+ "d.M.yyyy H:mm:ss",
+ "d' de 'MMMM' de 'yyyy H'h'm'min's's' z",
+ "dd. MMMM yyyy HH:mm:ss z",
+ "d-M-yyyy H:mm:ss",
+ "EEEE''d MMMM G yyyy, H' 'm' 'ss' '",
+ "dd.MMM.yyyy HH:mm:ss",
+ "yy-MM-dd h:mm:ss.a",
+ "d' de 'MMMM' de 'yyyy hh:mm:ss a z",
+ "EEEE d MMMM yyyy H' h 'mm' min 'ss' s 'z",
+ "d MMMM yyyy H:mm:ss",
+ "d/MM/yyyy hh:mm:ss a",
+ "EEEE, d, MMMM yyyy HH:mm:ss z",
+ "EEEE, d. MMMM yyyy HH.mm.' h' z",
+ "EEEE, d' / 'MMMM' / 'yyyy HH:mm:ss z",
+ "d/MM/yyyy HH:mm:ss",
+ "d MMMM yyyy H:mm:ss z",
+ "MMMM d, yyyy h:mm:ss a z",
+ "yyyy. MMMM d. H:mm:ss z",
+ "d' de 'MMMM' de 'yyyy H:mm:ss z",
+ "EEEE, MMMM d, yyyy h:mm:ss a z",
+ "d/M/yyyy H:mm:ss",
+ "d-MMM-yy HH:mm:ss",
+ "EEEE d' de 'MMMM' de 'yyyy hh:mm:ss a z",
+ "yyyy'M'd' ahh'mm'ss'",
+ "yyyy'MM'dd' EEEE ahh'mm'ss'",
+ "EEEE, d MMMM yyyy HH:mm:ss z",
+
+ //6990146: 'Y' for year; 'X' for time zone; 'u' for day number of the week
+ "d/M/YYYY H:mm:ss",
+ "d-MMM-YY HH:mm:ss",
+ "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a X",
+ "YYYY M d ahh:mm:ss",
+ "YYYY MM dd EEEE u ahh/mm/ss",
+ "EEEE, u, d MMMM YYYY HH:mm:ss X",
+ "YYYY M d Z ahh mm ss",
+ "YYYY-MM-dd EEEE u ahh-mm-ss",
+
+ //*added for sr-Latn*
+ "EEEE, dd. MMMM y. HH.mm.ss zzzz",
+ "dd. MMMM y. HH.mm.ss z",
+ "dd.MM.y. HH.mm.ss",
+ "d.M.yy. HH.mm"
+ };
+
+ private static String[] invalidPat = {
+ "yyyy'M'd' ahh:mm:ss",
+ "EEEe d MM MM yyyy HH' h 'mm zzzZ",
+ "d MMMM\\ yyyy, H' 'm' 'g",
+ "EEEE d' @# MMMMde 'yyys HHH'mm z",
+ "yyyy'MMe 2 #dd' EEEEahh'mm'ss' z,z",
+ "yyyy.M.d H;mm.ses",
+ "EEEe, d MMMM yyyy h:mm:ss a z",
+ "EEEE, MMMM d, 'y y y y h:mm:ss 'o''clock' a z",
+ "dd MMMM yyyy 0HHcl:mm:ss z",
+ "d.M_M_y.yy1yy HextH:mm|45:",
+ "d,D MMMTTTTTTTTTKM yy|+yy HH:m m:ss z",
+ "d-MDtM M-yy H:mm:ss",
+ "yyyy/M///m/nM/d Dd H:m$m:s s",
+ "EEEE, dd. MMMM yyyy HH:m'''m' Uhr 'z",
+ //6990146
+ "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a x",
+ "EEEE, U, d MMMM YYYY HH:mm:ss Z"
+ };
+
+ private static Locale[] locales = DateFormat.getAvailableLocales();
+ private static Object[][] dfAllLocalesObj = createAllLocales();
+ private static Object[][] invalidPatObj = createPatternObj(invalidPat);
+ private static Object[][] validPatObj = createPatternObj(validPat);
+
+ private static Object[][] createAllLocales() {
+ Object[][] objArray = new Object[locales.length][];
+ for (int i = 0; i < locales.length; i++) {
+ objArray[i] = new Object[1];
+ objArray[i][0] = locales[i];
+ }
+ return objArray;
+ }
+
+ private static Object[][] createPatternObj(String[] pattern){
+ Object[][] objArray = new Object[locales.length * pattern.length][];
+ int k = 0;
+ for (int i = 0; i < locales.length; i++) {
+ for (int j = 0; j < pattern.length; j++) {
+ objArray[k] = new Object[2];
+ objArray[k][0] = pattern[j];
+ objArray[k][1] = locales[i];
+ k = k + 1;
+ }
+ }
+ return objArray;
+ }
+
+ @DataProvider(name = "dfAllLocalesObj")
+ Object[][] dfAllLocalesObj() {
+ return dfAllLocalesObj;
+ }
+
+ @DataProvider(name = "invalidPatternObj")
+ Object[][] invalidPatternObj() {
+ return invalidPatObj;
+ }
+
+ @DataProvider(name = "validPatternObj")
+ Object[][] validPatternObj() {
+ return validPatObj;
+ }
+
+ //check Constructors for invalid pattern
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException1(String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern);
+ }
+
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException2(String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern, new DateFormatSymbols());
+ }
+
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException3 (String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern, Locale.getDefault());
+ }
+
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException4(String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat().applyPattern(pattern);
+ }
+
+ //check Constructors for null pattern
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException1(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(null);
+ }
+
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException2(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(null, new DateFormatSymbols());
+ }
+
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException3(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(null, Locale.getDefault());
+ }
+
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException4(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat().applyPattern(null);
+ }
+
+ @Test(dataProvider = "validPatternObj")
+ //check Constructors for valid pattern
+ public void testValidPattern(String pattern, Locale loc) {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern);
+ new SimpleDateFormat(pattern, new DateFormatSymbols());
+ new SimpleDateFormat(pattern, Locale.getDefault());
+ new SimpleDateFormat().applyPattern(pattern);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Format/DecimalFormat/SetGroupingSizeTest.java Wed Oct 16 11:23:46 2019 +0200
@@ -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.
+ */
+
+/*
+ * @test
+ * @bug 8212749
+ * @summary test whether input value check for
+ * DecimalFormat.setGroupingSize(int) works correctly.
+ * @run testng/othervm SetGroupingSizeTest
+ */
+
+import java.text.DecimalFormat;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class SetGroupingSizeTest {
+
+ @DataProvider
+ public static Object[][] validGroupingSizes() {
+ return new Object[][] {
+ { 0 },
+ { Byte.MAX_VALUE },
+ };
+ }
+
+ @DataProvider
+ public static Object[][] invalidGroupingSizes() {
+ return new Object[][] {
+ { Byte.MIN_VALUE - 1 },
+ { Byte.MIN_VALUE },
+ { -1 },
+ { Byte.MAX_VALUE + 1 },
+ { Integer.MIN_VALUE },
+ { Integer.MAX_VALUE },
+ };
+ }
+
+ @Test(dataProvider = "validGroupingSizes")
+ public void test_validGroupingSize(int newVal) {
+ DecimalFormat df = new DecimalFormat();
+ df.setGroupingSize(newVal);
+ assertEquals(df.getGroupingSize(), newVal);
+ }
+
+ @Test(dataProvider = "invalidGroupingSizes",
+ expectedExceptions = IllegalArgumentException.class)
+ public void test_invalidGroupingSize(int newVal) {
+ DecimalFormat df = new DecimalFormat();
+ df.setGroupingSize(newVal);
+ }
+}
--- a/test/jdk/java/util/Locale/Bug8040211.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/java/util/Locale/Bug8040211.java Wed Oct 16 11:23:46 2019 +0200
@@ -23,9 +23,9 @@
/*
* @test
- * @bug 8040211 8191404 8203872 8222980
+ * @bug 8040211 8191404 8203872 8222980 8225435
* @summary Checks the IANA language subtag registry data update
- * (LSR Revision: 2019-04-03) with Locale and Locale.LanguageRange
+ * (LSR Revision: 2019-09-16) with Locale and Locale.LanguageRange
* class methods.
* @run main Bug8040211
*/
@@ -42,6 +42,84 @@
static boolean err = false;
+ private static final String ACCEPT_LANGUAGE =
+ "Accept-Language: aam, adp, aog, aue, bcg, cey, cqu, dif, ema,"
+ + " en-gb-oed, gti, kdz, koj, kwq, kxe, lii, lmm, lsn, lsv, lvi, mtm,"
+ + " ngv, nns, oyb, phr, pnd, pub, snz, suj, szy,taj, tjj, tjp, tvx,"
+ + " uss, uth, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4";
+ private static final List<LanguageRange> EXPECTED_RANGE_LIST = List.of(
+ new LanguageRange("aam", 1.0),
+ new LanguageRange("aas", 1.0),
+ new LanguageRange("adp", 1.0),
+ new LanguageRange("dz", 1.0),
+ new LanguageRange("aog", 1.0),
+ new LanguageRange("myd", 1.0),
+ new LanguageRange("aue", 1.0),
+ new LanguageRange("ktz", 1.0),
+ new LanguageRange("bcg", 1.0),
+ new LanguageRange("bgm", 1.0),
+ new LanguageRange("cey", 1.0),
+ new LanguageRange("cqu", 1.0),
+ new LanguageRange("quh", 1.0),
+ new LanguageRange("dif", 1.0),
+ new LanguageRange("dit", 1.0),
+ new LanguageRange("ema", 1.0),
+ new LanguageRange("uok", 1.0),
+ new LanguageRange("en-gb-oed", 1.0),
+ new LanguageRange("en-gb-oxendict", 1.0),
+ new LanguageRange("gti", 1.0),
+ new LanguageRange("nyc", 1.0),
+ new LanguageRange("kdz", 1.0),
+ new LanguageRange("ncp", 1.0),
+ new LanguageRange("koj", 1.0),
+ new LanguageRange("kwv", 1.0),
+ new LanguageRange("kwq", 1.0),
+ new LanguageRange("yam", 1.0),
+ new LanguageRange("kxe", 1.0),
+ new LanguageRange("tvd", 1.0),
+ new LanguageRange("lii", 1.0),
+ new LanguageRange("raq", 1.0),
+ new LanguageRange("lmm", 1.0),
+ new LanguageRange("rmx", 1.0),
+ new LanguageRange("lsn", 1.0),
+ new LanguageRange("lsv", 1.0),
+ new LanguageRange("lvi", 1.0),
+ new LanguageRange("mtm", 1.0),
+ new LanguageRange("ymt", 1.0),
+ new LanguageRange("ngv", 1.0),
+ new LanguageRange("nnx", 1.0),
+ new LanguageRange("nns", 1.0),
+ new LanguageRange("nbr", 1.0),
+ new LanguageRange("oyb", 1.0),
+ new LanguageRange("thx", 1.0),
+ new LanguageRange("skk", 1.0),
+ new LanguageRange("jeg", 1.0),
+ new LanguageRange("phr", 1.0),
+ new LanguageRange("pmu", 1.0),
+ new LanguageRange("pnd", 1.0),
+ new LanguageRange("pub", 1.0),
+ new LanguageRange("puz", 1.0),
+ new LanguageRange("snz", 1.0),
+ new LanguageRange("asd", 1.0),
+ new LanguageRange("suj", 1.0),
+ new LanguageRange("szy", 1.0),
+ new LanguageRange("taj", 1.0),
+ new LanguageRange("tsf", 1.0),
+ new LanguageRange("tjj", 1.0),
+ new LanguageRange("tjp", 1.0),
+ new LanguageRange("tvx", 1.0),
+ new LanguageRange("uss", 1.0),
+ new LanguageRange("uth", 1.0),
+ new LanguageRange("wkr", 0.9),
+ new LanguageRange("ar-hyw", 0.8),
+ new LanguageRange("yug", 0.5),
+ new LanguageRange("yuu", 0.5),
+ new LanguageRange("gfx", 0.4),
+ new LanguageRange("oun", 0.4),
+ new LanguageRange("mwj", 0.4),
+ new LanguageRange("vaj", 0.4)
+ );
+
public static void main(String[] args) {
testLanguageRange();
testLocale();
@@ -66,70 +144,15 @@
private static void test_parse() {
boolean error = false;
- String str = "Accept-Language: aam, adp, aue, bcg, cqu, ema,"
- + " en-gb-oed, gti, kdz, koj, kwq, kxe, lii, lmm, mtm, ngv,"
- + " oyb, phr, pub, suj, taj;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4";
- ArrayList<LanguageRange> expected = new ArrayList<>();
- expected.add(new LanguageRange("aam", 1.0));
- expected.add(new LanguageRange("aas", 1.0));
- expected.add(new LanguageRange("adp", 1.0));
- expected.add(new LanguageRange("dz", 1.0));
- expected.add(new LanguageRange("aue", 1.0));
- expected.add(new LanguageRange("ktz", 1.0));
- expected.add(new LanguageRange("bcg", 1.0));
- expected.add(new LanguageRange("bgm", 1.0));
- expected.add(new LanguageRange("cqu", 1.0));
- expected.add(new LanguageRange("quh", 1.0));
- expected.add(new LanguageRange("ema", 1.0));
- expected.add(new LanguageRange("uok", 1.0));
- expected.add(new LanguageRange("en-gb-oed", 1.0));
- expected.add(new LanguageRange("en-gb-oxendict", 1.0));
- expected.add(new LanguageRange("gti", 1.0));
- expected.add(new LanguageRange("nyc", 1.0));
- expected.add(new LanguageRange("kdz", 1.0));
- expected.add(new LanguageRange("ncp", 1.0));
- expected.add(new LanguageRange("koj", 1.0));
- expected.add(new LanguageRange("kwv", 1.0));
- expected.add(new LanguageRange("kwq", 1.0));
- expected.add(new LanguageRange("yam", 1.0));
- expected.add(new LanguageRange("kxe", 1.0));
- expected.add(new LanguageRange("tvd", 1.0));
- expected.add(new LanguageRange("lii", 1.0));
- expected.add(new LanguageRange("raq", 1.0));
- expected.add(new LanguageRange("lmm", 1.0));
- expected.add(new LanguageRange("rmx", 1.0));
- expected.add(new LanguageRange("mtm", 1.0));
- expected.add(new LanguageRange("ymt", 1.0));
- expected.add(new LanguageRange("ngv", 1.0));
- expected.add(new LanguageRange("nnx", 1.0));
- expected.add(new LanguageRange("oyb", 1.0));
- expected.add(new LanguageRange("thx", 1.0));
- expected.add(new LanguageRange("skk", 1.0));
- expected.add(new LanguageRange("jeg", 1.0));
- expected.add(new LanguageRange("phr", 1.0));
- expected.add(new LanguageRange("pmu", 1.0));
- expected.add(new LanguageRange("pub", 1.0));
- expected.add(new LanguageRange("puz", 1.0));
- expected.add(new LanguageRange("suj", 1.0));
- expected.add(new LanguageRange("xsj", 1.0));
- expected.add(new LanguageRange("taj", 0.9));
- expected.add(new LanguageRange("tsf", 0.9));
- expected.add(new LanguageRange("ar-hyw", 0.8));
- expected.add(new LanguageRange("yug", 0.5));
- expected.add(new LanguageRange("yuu", 0.5));
- expected.add(new LanguageRange("gfx", 0.4));
- expected.add(new LanguageRange("oun", 0.4));
- expected.add(new LanguageRange("mwj", 0.4));
- expected.add(new LanguageRange("vaj", 0.4));
- List<LanguageRange> got = LanguageRange.parse(str);
- if (!areEqual(expected, got)) {
+ List<LanguageRange> got = LanguageRange.parse(ACCEPT_LANGUAGE);
+ if (!areEqual(EXPECTED_RANGE_LIST, got)) {
error = true;
System.err.println(" language parse() test failed.");
}
if (error) {
err = true;
- System.err.println(" test_parse() failed.");
+ System.out.println(" test_parse() failed.");
} else {
System.out.println(" test_parse() passed.");
}
@@ -152,7 +175,7 @@
+ ", weight=" + lr.getWeight());
}
- System.out.println(" Actual size=" + actualSize);
+ System.err.println(" Actual size=" + actualSize);
for (LanguageRange lr : got) {
System.err.println(" range=" + lr.getRange()
+ ", weight=" + lr.getWeight());
@@ -351,11 +374,11 @@
String tags,
String expectedTags,
String actualTags) {
- System.out.println("\nIncorrect " + methodName + " result.");
- System.out.println(" Priority list : " + priorityList);
- System.out.println(" Language tags : " + tags);
- System.out.println(" Expected value : " + expectedTags);
- System.out.println(" Actual value : " + actualTags);
+ System.err.println("\nIncorrect " + methodName + " result.");
+ System.err.println(" Priority list : " + priorityList);
+ System.err.println(" Language tags : " + tags);
+ System.err.println(" Expected value : " + expectedTags);
+ System.err.println(" Actual value : " + actualTags);
}
}
--- a/test/jdk/jdk/jfr/event/io/EvilInstrument.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/jdk/jfr/event/io/EvilInstrument.java Wed Oct 16 11:23:46 2019 +0200
@@ -52,6 +52,7 @@
* @library /test/lib /test/jdk
* @modules java.instrument
*
+ * @build jdk.jfr.event.io.EvilInstrument
* @run shell MakeJAR.sh EvilInstrument 'Can-Redefine-Classes: true'
* @run main/othervm -javaagent:EvilInstrument.jar jdk.jfr.event.io.EvilInstrument
*/
--- a/test/jdk/sun/security/util/FilePermCompat/Flag.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/jdk/sun/security/util/FilePermCompat/Flag.java Wed Oct 16 11:23:46 2019 +0200
@@ -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
@@ -23,22 +23,84 @@
/*
* @test
- * @bug 8164705
+ * @bug 8164705 8209901
+ * @library /test/jdk/java/security/testlibrary
+ * @modules java.base/jdk.internal.misc
* @summary check jdk.filepermission.canonicalize
- * @run main/othervm/policy=flag.policy
- * -Djdk.io.permissionsUseCanonicalPath=true Flag true true
- * @run main/othervm/policy=flag.policy
- * -Djdk.io.permissionsUseCanonicalPath=false Flag false true
- * @run main/othervm/policy=flag.policy Flag false true
*/
import java.io.File;
import java.io.FilePermission;
import java.lang.*;
+import java.nio.file.Path;
public class Flag {
public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ String policy = Path.of(
+ System.getProperty("test.src"), "flag.policy").toString();
+
+ // effectively true
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .prop("jdk.io.permissionsUseCanonicalPath", "true")
+ .args("run", "true", "true")
+ .start()
+ .waitFor(0);
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .secprop("jdk.io.permissionsUseCanonicalPath", "true")
+ .args("run", "true", "true")
+ .start()
+ .waitFor(0);
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .secprop("jdk.io.permissionsUseCanonicalPath", "false")
+ .prop("jdk.io.permissionsUseCanonicalPath", "true")
+ .args("run", "true", "true")
+ .start()
+ .waitFor(0);
+
+ // effectively false
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .prop("jdk.io.permissionsUseCanonicalPath", "false")
+ .args("run", "false", "true")
+ .start()
+ .waitFor(0);
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .secprop("jdk.io.permissionsUseCanonicalPath", "false")
+ .args("run", "false", "true")
+ .start()
+ .waitFor(0);
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .secprop("jdk.io.permissionsUseCanonicalPath", "true")
+ .prop("jdk.io.permissionsUseCanonicalPath", "false")
+ .args("run", "false", "true")
+ .start()
+ .waitFor(0);
+ Proc.create("Flag")
+ .prop("java.security.manager", "")
+ .prop("java.security.policy", policy)
+ .args("run", "false", "true")
+ .start()
+ .waitFor(0);
+ } else {
+ run(args);
+ }
+ }
+
+ static void run(String[] args) throws Exception {
+
boolean test1;
boolean test2;
@@ -55,8 +117,8 @@
test2 = false;
}
- if (test1 != Boolean.parseBoolean(args[0]) ||
- test2 != Boolean.parseBoolean(args[1])) {
+ if (test1 != Boolean.parseBoolean(args[1]) ||
+ test2 != Boolean.parseBoolean(args[2])) {
throw new Exception("Test failed: " + test1 + " " + test2);
}
}
--- a/test/langtools/jdk/javadoc/tool/TestScriptInComment.java Wed Oct 16 01:16:12 2019 +0200
+++ b/test/langtools/jdk/javadoc/tool/TestScriptInComment.java Wed Oct 16 11:23:46 2019 +0200
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8138725
+ * @bug 8138725 8226765
* @summary test --allow-script-in-comments
* @modules jdk.javadoc/jdk.javadoc.internal.tool
*/
@@ -63,6 +63,10 @@
WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space
SP("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute
ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute
+ OME("<img alt='1' onmouseenter='#ALERT'>", true), // onmouseenter event handler attribute
+ OML("<img alt='1' onmouseleave='#ALERT'>", true), // onmouseleave event handler attribute
+ OFI("<a href='#' onfocusin='#ALERT'>x</a>", true), // onfocusin event handler attribute
+ OBE("<a onbogusevent='#ALERT'>x</a>", true), // bogus/future event handler attribute
URI("<a href='javascript:#ALERT'>x</a>", true); // javascript URI
/**