--- a/.hgtags Wed Nov 20 12:18:46 2019 +0530
+++ b/.hgtags Thu Nov 21 13:50:11 2019 +0530
@@ -596,3 +596,4 @@
c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21
83810b7d12e7ff761ad3dd91f323a22dad96f108 jdk-14+22
15936b142f86731afa4b1a2c0fe4a01e806c4944 jdk-14+23
+438337c846fb071900ddb6922bddf8b3e895a514 jdk-14+24
--- a/make/data/fontconfig/aix.fontconfig.properties Wed Nov 20 12:18:46 2019 +0530
+++ b/make/data/fontconfig/aix.fontconfig.properties Thu Nov 21 13:50:11 2019 +0530
@@ -1,6 +1,6 @@
#
#
-# Copyright (c) 2013 SAP SE. All rights reserved.
+# Copyright (c) 2013, 2019 SAP SE. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -48,12 +48,12 @@
dialog.plain.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialog.plain.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialog.plain.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialog.plain.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialog.plain.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.plain.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialog.plain.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialog.plain.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.plain.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialog.plain.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialog.plain.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialog.plain.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialog.plain.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso8859-1
dialog.bold.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -61,12 +61,12 @@
dialog.bold.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialog.bold.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialog.bold.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialog.bold.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialog.bold.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.bold.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialog.bold.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialog.bold.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.bold.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialog.bold.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialog.bold.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialog.bold.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialog.bold.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso8859-1
dialog.italic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -74,12 +74,12 @@
dialog.italic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialog.italic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialog.italic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialog.italic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialog.italic.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.italic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialog.italic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialog.italic.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.italic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialog.italic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialog.italic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialog.italic.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialog.italic.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso8859-1
dialog.bolditalic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -87,12 +87,12 @@
dialog.bolditalic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialog.bolditalic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialog.bolditalic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialog.bolditalic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialog.bolditalic.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.bolditalic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialog.bolditalic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialog.bolditalic.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialog.bolditalic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialog.bolditalic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialog.bolditalic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialog.bolditalic.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialog.bolditalic.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso8859-1
dialoginput.plain.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -100,12 +100,12 @@
dialoginput.plain.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialoginput.plain.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialoginput.plain.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialoginput.plain.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialoginput.plain.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.plain.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialoginput.plain.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialoginput.plain.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.plain.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialoginput.plain.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialoginput.plain.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialoginput.plain.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialoginput.plain.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso8859-1
dialoginput.bold.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -113,12 +113,12 @@
dialoginput.bold.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialoginput.bold.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialoginput.bold.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialoginput.bold.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialoginput.bold.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.bold.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialoginput.bold.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialoginput.bold.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.bold.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialoginput.bold.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialoginput.bold.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialoginput.bold.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialoginput.bold.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso8859-1
dialoginput.italic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -126,12 +126,12 @@
dialoginput.italic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialoginput.italic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialoginput.italic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialoginput.italic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialoginput.italic.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.italic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialoginput.italic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialoginput.italic.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.italic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialoginput.italic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialoginput.italic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialoginput.italic.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialoginput.italic.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso8859-1
dialoginput.bolditalic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -139,12 +139,12 @@
dialoginput.bolditalic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
dialoginput.bolditalic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
dialoginput.bolditalic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-dialoginput.bolditalic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+dialoginput.bolditalic.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.bolditalic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-dialoginput.bolditalic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+dialoginput.bolditalic.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
dialoginput.bolditalic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-dialoginput.bolditalic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-dialoginput.bolditalic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+dialoginput.bolditalic.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+dialoginput.bolditalic.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso8859-1
sansserif.plain.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -152,12 +152,12 @@
sansserif.plain.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
sansserif.plain.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
sansserif.plain.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-sansserif.plain.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+sansserif.plain.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.plain.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-sansserif.plain.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+sansserif.plain.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.plain.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-sansserif.plain.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-sansserif.plain.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+sansserif.plain.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+sansserif.plain.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso8859-1
sansserif.bold.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -165,12 +165,12 @@
sansserif.bold.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
sansserif.bold.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
sansserif.bold.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-sansserif.bold.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+sansserif.bold.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.bold.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-sansserif.bold.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+sansserif.bold.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.bold.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-sansserif.bold.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-sansserif.bold.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+sansserif.bold.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+sansserif.bold.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso8859-1
sansserif.italic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -178,12 +178,12 @@
sansserif.italic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
sansserif.italic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
sansserif.italic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-sansserif.italic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+sansserif.italic.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.italic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-sansserif.italic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+sansserif.italic.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.italic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-sansserif.italic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-sansserif.italic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+sansserif.italic.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+sansserif.italic.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso8859-1
sansserif.bolditalic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -191,12 +191,12 @@
sansserif.bolditalic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
sansserif.bolditalic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
sansserif.bolditalic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-sansserif.bolditalic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+sansserif.bolditalic.japanese-iso10646=-monotype-wt sans j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.bolditalic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-sansserif.bolditalic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+sansserif.bolditalic.korean-iso10646=-monotype-wt sans k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
sansserif.bolditalic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-sansserif.bolditalic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-sansserif.bolditalic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+sansserif.bolditalic.chinese-iso10646=-monotype-wt sans sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+sansserif.bolditalic.taiwanese-iso10646=-monotype-wt sans tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.plain.latin-1=-*-times new roman-medium-r-normal--*-%d-100-100-p-*-iso8859-1
serif.plain.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -204,12 +204,12 @@
serif.plain.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
serif.plain.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
serif.plain.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-serif.plain.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+serif.plain.japanese-iso10646=-monotype-wt serif j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.plain.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-serif.plain.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+serif.plain.korean-iso10646=-monotype-wt serif k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.plain.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-serif.plain.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-serif.plain.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+serif.plain.chinese-iso10646=-monotype-wt serif sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+serif.plain.taiwanese-iso10646=-monotype-wt serif tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.bold.latin-1=-*-times new roman-bold-r-normal--*-%d-100-100-p-*-iso8859-1
serif.bold.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -217,12 +217,12 @@
serif.bold.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
serif.bold.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
serif.bold.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-serif.bold.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+serif.bold.japanese-iso10646=-monotype-wt serif j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.bold.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-serif.bold.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+serif.bold.korean-iso10646=-monotype-wt serif k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.bold.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-serif.bold.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-serif.bold.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+serif.bold.chinese-iso10646=-monotype-wt serif sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+serif.bold.taiwanese-iso10646=-monotype-wt serif tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.italic.latin-1=-*-times new roman-medium-i-normal--*-%d-100-100-p-*-iso8859-1
@@ -231,12 +231,12 @@
serif.italic.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
serif.italic.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
serif.italic.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-serif.italic.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+serif.italic.japanese-iso10646=-monotype-wt serif j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.italic.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-serif.italic.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+serif.italic.korean-iso10646=-monotype-wt serif k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.italic.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-serif.italic.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-serif.italic.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+serif.italic.chinese-iso10646=-monotype-wt serif sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+serif.italic.taiwanese-iso10646=-monotype-wt serif tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.bolditalic.latin-1=-*-times new roman-bold-i-normal--*-%d-100-100-p-*-iso8859-1
serif.bolditalic.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
@@ -244,12 +244,12 @@
serif.bolditalic.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
serif.bolditalic.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
serif.bolditalic.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-serif.bolditalic.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+serif.bolditalic.japanese-iso10646=-monotype-wt serif j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.bolditalic.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-serif.bolditalic.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+serif.bolditalic.korean-iso10646=-monotype-wt serif k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
serif.bolditalic.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-serif.bolditalic.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-serif.bolditalic.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+serif.bolditalic.chinese-iso10646=-monotype-wt serif sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+serif.bolditalic.taiwanese-iso10646=-monotype-wt serif tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso8859-1
monospaced.plain.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -257,12 +257,12 @@
monospaced.plain.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
monospaced.plain.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
monospaced.plain.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-monospaced.plain.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+monospaced.plain.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.plain.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-monospaced.plain.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+monospaced.plain.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.plain.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-monospaced.plain.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-monospaced.plain.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+monospaced.plain.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+monospaced.plain.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso8859-1
monospaced.bold.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -270,12 +270,12 @@
monospaced.bold.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
monospaced.bold.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
monospaced.bold.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-monospaced.bold.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+monospaced.bold.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.bold.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-monospaced.bold.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+monospaced.bold.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.bold.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-monospaced.bold.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-monospaced.bold.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+monospaced.bold.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+monospaced.bold.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso8859-1
monospaced.italic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -283,12 +283,12 @@
monospaced.italic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
monospaced.italic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
monospaced.italic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-monospaced.italic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+monospaced.italic.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.italic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-monospaced.italic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+monospaced.italic.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.italic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-monospaced.italic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-monospaced.italic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+monospaced.italic.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+monospaced.italic.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso8859-1
monospaced.bolditalic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
@@ -296,12 +296,12 @@
monospaced.bolditalic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
monospaced.bolditalic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
monospaced.bolditalic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
-monospaced.bolditalic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
+monospaced.bolditalic.japanese-iso10646=-monotype-wt sans duo j-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.bolditalic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
-monospaced.bolditalic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
+monospaced.bolditalic.korean-iso10646=-monotype-wt sans duo k-medium-r-normal--*-%d-75-75-*-*-iso10646-1
monospaced.bolditalic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
-monospaced.bolditalic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
-monospaced.bolditalic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+monospaced.bolditalic.chinese-iso10646=-monotype-wt sans duo sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1
+monospaced.bolditalic.taiwanese-iso10646=-monotype-wt sans duo tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1
# Search Sequences
@@ -353,33 +353,33 @@
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
-filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
+filename.-monotype-wt_serif_j-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wt__j__b.ttf
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_k.ttf
-filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_k.ttf
+filename.-monotype-wt_serif_k-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wt__k__b.ttf
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
-filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
+filename.-monotype-wt_serif_sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wt__s__b.ttf
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
-filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
-filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_t.ttf
+filename.-monotype-wt_serif_sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wt__s__b.ttf
+filename.-monotype-wt_serif_tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wt__tt_b.ttf
filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
-filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
+filename.-monotype-wt_sans_duo_j-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wtsdj__b.ttf
filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdk.ttf
-filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdk.ttf
+filename.-monotype-wt_sans_duo_k-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wtsdk__b.ttf
filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansds.ttf
-filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansds.ttf
-filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdt.ttf
+filename.-monotype-wt_sans_duo_sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wtsds__b.ttf
+filename.-monotype-wt_sans_duo_tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wtsdtt_b.ttf
filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
-filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
+filename.-monotype-wt_sans_j-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wts_j__b.ttf
filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_k.ttf
-filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_k.ttf
+filename.-monotype-wt_sans_k-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wts_k__b.ttf
filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_s.ttf
-filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_s.ttf
-filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_t.ttf
+filename.-monotype-wt_sans_sc-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wts_s__b.ttf
+filename.-monotype-wt_sans_tw-medium-r-normal--*-%d-75-75-*-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/TrueType/wts_tt_b.ttf
filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-iso8859-15=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-iso8859-15=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1532,7 +1532,7 @@
Label L_rtm_retry, L_decrement_retry, L_on_abort;
int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
- // Without cast to int32_t a movptr will destroy r10 which is typically obj
+ // Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value()));
movptr(boxReg, tmpReg); // Save ObjectMonitor address
@@ -1602,11 +1602,11 @@
#endif // INCLUDE_RTM_OPT
-// Fast_Lock and Fast_Unlock used by C2
+// fast_lock and fast_unlock used by C2
// Because the transitions from emitted code to the runtime
// monitorenter/exit helper stubs are so slow it's critical that
-// we inline both the stack-locking fast-path and the inflated fast path.
+// we inline both the stack-locking fast path and the inflated fast path.
//
// See also: cmpFastLock and cmpFastUnlock.
//
@@ -1615,7 +1615,7 @@
// option would be to emit TrySlowEnter and TrySlowExit methods
// at startup-time. These methods would accept arguments as
// (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure
-// indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply
+// indications in the icc.ZFlag. fast_lock and fast_unlock would simply
// marshal the arguments and emit calls to TrySlowEnter and TrySlowExit.
// In practice, however, the # of lock sites is bounded and is usually small.
// Besides the call overhead, TrySlowEnter and TrySlowExit might suffer
@@ -1634,8 +1634,8 @@
//
// TODO:
//
-// * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr).
-// This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals.
+// * Arrange for C2 to pass "Self" into fast_lock and fast_unlock in one of the registers (scr).
+// This avoids manifesting the Self pointer in the fast_lock and fast_unlock terminals.
// Given TLAB allocation, Self is usually manifested in a register, so passing it into
// the lock operators would typically be faster than reifying Self.
//
@@ -1661,14 +1661,14 @@
// * use jccb and jmpb instead of jcc and jmp to improve code density.
// But beware of excessive branch density on AMD Opterons.
//
-// * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success
-// or failure of the fast-path. If the fast-path fails then we pass
-// control to the slow-path, typically in C. In Fast_Lock and
-// Fast_Unlock we often branch to DONE_LABEL, just to find that C2
+// * Both fast_lock and fast_unlock set the ICC.ZF to indicate success
+// or failure of the fast path. If the fast path fails then we pass
+// control to the slow path, typically in C. In fast_lock and
+// fast_unlock we often branch to DONE_LABEL, just to find that C2
// will emit a conditional branch immediately after the node.
// So we have branches to branches and lots of ICC.ZF games.
// Instead, it might be better to have C2 pass a "FailureLabel"
-// into Fast_Lock and Fast_Unlock. In the case of success, control
+// into fast_lock and fast_unlock. In the case of success, control
// will drop through the node. ICC.ZF is undefined at exit.
// In the case of failure, the node will branch directly to the
// FailureLabel
@@ -1813,7 +1813,7 @@
movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
xorptr(boxReg, boxReg); // set icc.ZFlag = 1 to indicate success
- // If the CAS fails we can either retry or pass control to the slow-path.
+ // If the CAS fails we can either retry or pass control to the slow path.
// We use the latter tactic.
// Pass the CAS result in the icc.ZFlag into DONE_LABEL
// If the CAS was successful ...
@@ -1821,14 +1821,13 @@
// Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
// Intentional fall-through into DONE_LABEL ...
#else // _LP64
- // It's inflated
+ // It's inflated and we use scrReg for ObjectMonitor* in this section.
movq(scrReg, tmpReg);
xorq(tmpReg, tmpReg);
-
lock();
cmpxchgptr(r15_thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
// Unconditionally set box->_displaced_header = markWord::unused_mark().
- // Without cast to int32_t movptr will destroy r10 which is typically obj.
+ // Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value()));
// Intentional fall-through into DONE_LABEL ...
// Propagate ICC.ZF from CAS above into DONE_LABEL.
@@ -1844,9 +1843,9 @@
bind(DONE_LABEL);
// At DONE_LABEL the icc ZFlag is set as follows ...
- // Fast_Unlock uses the same protocol.
+ // fast_unlock uses the same protocol.
// ZFlag == 1 -> Success
- // ZFlag == 0 -> Failure - force control through the slow-path
+ // ZFlag == 0 -> Failure - force control through the slow path
}
// obj: object to unlock
@@ -1855,7 +1854,7 @@
//
// Some commentary on balanced locking:
//
-// Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites.
+// fast_lock and fast_unlock are emitted only for provably balanced lock sites.
// Methods that don't have provably balanced locking are forced to run in the
// interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
// The interpreter provides two properties:
@@ -1876,7 +1875,7 @@
// should not be unlocked by "normal" java-level locking and vice-versa. The specification
// doesn't specify what will occur if a program engages in such mixed-mode locking, however.
// Arguably given that the spec legislates the JNI case as undefined our implementation
-// could reasonably *avoid* checking owner in Fast_Unlock().
+// could reasonably *avoid* checking owner in fast_unlock().
// In the interest of performance we elide m->Owner==Self check in unlock.
// A perfectly viable alternative is to elide the owner check except when
// Xcheck:jni is enabled.
@@ -1941,7 +1940,7 @@
// a costly MEMBAR or CAS. See synchronizer.cpp for details on how
// we detect and recover from the race that the 1-0 exit admits.
//
- // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier
+ // Conceptually fast_unlock() must execute a STST|LDST "release" barrier
// before it STs null into _owner, releasing the lock. Updates
// to data protected by the critical section must be visible before
// we drop the lock (and thus before any other thread could acquire
@@ -1990,6 +1989,7 @@
movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
jccb (Assembler::notZero, CheckSucc);
+ // Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
jmpb (DONE_LABEL);
@@ -1998,13 +1998,14 @@
bind (CheckSucc);
// The following optional optimization can be elided if necessary
- // Effectively: if (succ == null) goto SlowPath
+ // Effectively: if (succ == null) goto slow path
// The code reduces the window for a race, however,
// and thus benefits performance.
cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
jccb (Assembler::zero, LGoSlowPath);
xorptr(boxReg, boxReg);
+ // Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
// Memory barrier/fence
@@ -2039,7 +2040,7 @@
// If that didn't work, then another thread grabbed the
// lock so we're done (and exit was a success).
jccb (Assembler::notEqual, LSuccess);
- // Intentional fall-through into slow-path
+ // Intentional fall-through into slow path
bind (LGoSlowPath);
orl (boxReg, 1); // set ICC.ZF=0 to indicate failure
--- a/src/hotspot/os/bsd/os_bsd.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/os/bsd/os_bsd.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -3205,14 +3205,14 @@
}
#ifdef __APPLE__
-uint os::processor_id() {
- static volatile int* volatile apic_to_cpu_mapping = NULL;
- static volatile int next_cpu_id = 0;
-
- volatile int* mapping = OrderAccess::load_acquire(&apic_to_cpu_mapping);
+static volatile int* volatile apic_to_processor_mapping = NULL;
+static volatile int next_processor_id = 0;
+
+static inline volatile int* get_apic_to_processor_mapping() {
+ volatile int* mapping = OrderAccess::load_acquire(&apic_to_processor_mapping);
if (mapping == NULL) {
// Calculate possible number space for APIC ids. This space is not necessarily
- // in the range [0, number_of_cpus).
+ // in the range [0, number_of_processors).
uint total_bits = 0;
for (uint i = 0;; ++i) {
uint eax = 0xb; // Query topology leaf
@@ -3238,33 +3238,39 @@
mapping[i] = -1;
}
- if (!Atomic::replace_if_null(mapping, &apic_to_cpu_mapping)) {
+ if (!Atomic::replace_if_null(mapping, &apic_to_processor_mapping)) {
FREE_C_HEAP_ARRAY(int, mapping);
- mapping = OrderAccess::load_acquire(&apic_to_cpu_mapping);
+ mapping = OrderAccess::load_acquire(&apic_to_processor_mapping);
}
}
+ return mapping;
+}
+
+uint os::processor_id() {
+ volatile int* mapping = get_apic_to_processor_mapping();
+
uint eax = 0xb;
uint ebx;
uint ecx = 0;
uint edx;
- asm ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
+ __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
// Map from APIC id to a unique logical processor ID in the expected
// [0, num_processors) range.
uint apic_id = edx;
- int cpu_id = Atomic::load(&mapping[apic_id]);
-
- while (cpu_id < 0) {
+ int processor_id = Atomic::load(&mapping[apic_id]);
+
+ while (processor_id < 0) {
if (Atomic::cmpxchg(-2, &mapping[apic_id], -1)) {
- Atomic::store(Atomic::add(1, &next_cpu_id) - 1, &mapping[apic_id]);
+ Atomic::store(Atomic::add(1, &next_processor_id) - 1, &mapping[apic_id]);
}
- cpu_id = Atomic::load(&mapping[apic_id]);
+ processor_id = Atomic::load(&mapping[apic_id]);
}
- return (uint)cpu_id;
+ return (uint)processor_id;
}
#endif
--- a/src/hotspot/share/classfile/systemDictionary.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -540,7 +540,7 @@
assert(calledholdinglock,"must hold lock for notify");
assert((lockObject() != _system_loader_lock_obj && !is_parallelCapable(lockObject)), "unexpected double_lock_wait");
ObjectSynchronizer::notifyall(lockObject, THREAD);
- intptr_t recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD);
+ intx recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD);
SystemDictionary_lock->wait();
SystemDictionary_lock->unlock();
ObjectSynchronizer::reenter(lockObject, recursions, THREAD);
--- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -290,8 +290,8 @@
collect(gc_cause());
}
-void EpsilonHeap::safe_object_iterate(ObjectClosure *cl) {
- _space->safe_object_iterate(cl);
+void EpsilonHeap::object_iterate(ObjectClosure *cl) {
+ _space->object_iterate(cl);
}
void EpsilonHeap::print_on(outputStream *st) const {
--- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -103,10 +103,7 @@
virtual void do_full_collection(bool clear_all_soft_refs);
// Heap walking support
- virtual void safe_object_iterate(ObjectClosure* cl);
- virtual void object_iterate(ObjectClosure* cl) {
- safe_object_iterate(cl);
- }
+ virtual void object_iterate(ObjectClosure* cl);
// Object pinning support: every object is implicitly pinned
virtual bool supports_object_pinning() const { return true; }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -1166,10 +1166,6 @@
// Iterate over all objects, calling "cl.do_object" on each.
virtual void object_iterate(ObjectClosure* cl);
- virtual void safe_object_iterate(ObjectClosure* cl) {
- object_iterate(cl);
- }
-
// Iterate over heap regions, in address order, terminating the
// iteration early if the "do_heap_region" method returns "true".
void heap_region_iterate(HeapRegionClosure* blk) const;
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -213,7 +213,6 @@
size_t unsafe_max_tlab_alloc(Thread* thr) const;
void object_iterate(ObjectClosure* cl);
- void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); }
HeapWord* block_start(const void* addr) const;
bool block_is_obj(const HeapWord* addr) const;
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -387,10 +387,6 @@
// Iterate over all objects, calling "cl.do_object" on each.
virtual void object_iterate(ObjectClosure* cl) = 0;
- // Similar to object_iterate() except iterates only
- // over live objects.
- virtual void safe_object_iterate(ObjectClosure* cl) = 0;
-
// Returns the longest time (in ms) that has elapsed since the last
// time that any part of the heap was examined by a garbage collection.
virtual jlong millis_since_last_gc() = 0;
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1034,11 +1034,6 @@
_old_gen->object_iterate(cl);
}
-void GenCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
- _young_gen->safe_object_iterate(cl);
- _old_gen->safe_object_iterate(cl);
-}
-
Space* GenCollectedHeap::space_containing(const void* addr) const {
Space* res = _young_gen->space_containing(addr);
if (res != NULL) {
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -248,7 +248,6 @@
// Iteration functions.
void oop_iterate(OopIterateClosure* cl);
void object_iterate(ObjectClosure* cl);
- void safe_object_iterate(ObjectClosure* cl);
Space* space_containing(const void* addr) const;
// A CollectedHeap is divided into a dense sequence of "blocks"; that is,
--- a/src/hotspot/share/gc/shared/generation.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/generation.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -289,21 +289,6 @@
space_iterate(&blk);
}
-class GenerationSafeObjIterateClosure : public SpaceClosure {
- private:
- ObjectClosure* _cl;
- public:
- virtual void do_space(Space* s) {
- s->safe_object_iterate(_cl);
- }
- GenerationSafeObjIterateClosure(ObjectClosure* cl) : _cl(cl) {}
-};
-
-void Generation::safe_object_iterate(ObjectClosure* cl) {
- GenerationSafeObjIterateClosure blk(cl);
- space_iterate(&blk);
-}
-
#if INCLUDE_SERIALGC
void Generation::prepare_for_compaction(CompactPoint* cp) {
--- a/src/hotspot/share/gc/shared/generation.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/generation.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -470,11 +470,6 @@
// each.
virtual void object_iterate(ObjectClosure* cl);
- // Iterate over all safe objects in the generation, calling "cl.do_object" on
- // each. An object is safe if its references point to other objects in
- // the heap. This defaults to object_iterate() unless overridden.
- virtual void safe_object_iterate(ObjectClosure* cl);
-
// Apply "cl->do_oop" to (the address of) all and only all the ref fields
// in the current generation that contain pointers to objects in younger
// generations. Objects allocated since the last "save_marks" call are
--- a/src/hotspot/share/gc/shared/space.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/space.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -110,18 +110,6 @@
// we (or another worker thread) may already have scanned
// or planning to scan.
void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
-
- // Some collectors need to do special things whenever their dirty
- // cards are processed. For instance, CMS must remember mutator updates
- // (i.e. dirty cards) so as to re-scan mutated objects.
- // Such work can be piggy-backed here on dirty card scanning, so as to make
- // it slightly more efficient than doing a complete non-destructive pre-scan
- // of the card table.
- MemRegionClosure* pCl = _sp->preconsumptionDirtyCardClosure();
- if (pCl != NULL) {
- pCl->do_MemRegion(mr);
- }
-
HeapWord* bottom = mr.start();
HeapWord* last = mr.last();
HeapWord* top = mr.end();
@@ -498,12 +486,6 @@
object_iterate_from(bottom(), blk);
}
-// For a ContiguousSpace object_iterate() and safe_object_iterate()
-// are the same.
-void ContiguousSpace::safe_object_iterate(ObjectClosure* blk) {
- object_iterate(blk);
-}
-
void ContiguousSpace::object_iterate_from(HeapWord* mark, ObjectClosure* blk) {
while (mark < top()) {
blk->do_object(oop(mark));
@@ -511,21 +493,6 @@
}
}
-HeapWord*
-ContiguousSpace::object_iterate_careful(ObjectClosureCareful* blk) {
- HeapWord * limit = concurrent_iteration_safe_limit();
- assert(limit <= top(), "sanity check");
- for (HeapWord* p = bottom(); p < limit;) {
- size_t size = blk->do_object_careful(oop(p));
- if (size == 0) {
- return p; // failed at p
- } else {
- p += size;
- }
- }
- return NULL; // all done
-}
-
// Very general, slow implementation.
HeapWord* ContiguousSpace::block_start_const(const void* p) const {
assert(MemRegion(bottom(), end()).contains(p),
--- a/src/hotspot/share/gc/shared/space.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/space.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -94,10 +94,6 @@
return (HeapWord*)obj >= saved_mark_word();
}
- virtual MemRegionClosure* preconsumptionDirtyCardClosure() const {
- return NULL;
- }
-
// Returns a subregion of the space containing only the allocated objects in
// the space.
virtual MemRegion used_region() const = 0;
@@ -175,9 +171,6 @@
// each. Objects allocated by applications of the closure are not
// included in the iteration.
virtual void object_iterate(ObjectClosure* blk) = 0;
- // Similar to object_iterate() except only iterates over
- // objects whose internal references point to objects in the space.
- virtual void safe_object_iterate(ObjectClosure* blk) = 0;
// Create and return a new dirty card to oop closure. Can be
// overridden to return the appropriate type of closure
@@ -356,7 +349,6 @@
// definition of scanned_block_size/scanned_block_is_obj respectively.
class CompactibleSpace: public Space {
friend class VMStructs;
- friend class CompactibleFreeListSpace;
private:
HeapWord* _compaction_top;
CompactibleSpace* _next_compaction_space;
@@ -462,9 +454,6 @@
HeapWord* _first_dead;
HeapWord* _end_of_live;
- // Minimum size of a free block.
- virtual size_t minimum_free_block_size() const { return 0; }
-
// This the function is invoked when an allocation of an object covering
// "start" to "end occurs crosses the threshold; returns the next
// threshold. (The default implementation does nothing.)
@@ -584,18 +573,7 @@
// Iteration
void oop_iterate(OopIterateClosure* cl);
void object_iterate(ObjectClosure* blk);
- // For contiguous spaces this method will iterate safely over objects
- // in the space (i.e., between bottom and top) when at a safepoint.
- void safe_object_iterate(ObjectClosure* blk);
- // Iterate over as many initialized objects in the space as possible,
- // calling "cl.do_object_careful" on each. Return NULL if all objects
- // in the space (at the start of the iteration) were iterated over.
- // Return an address indicating the extent of the iteration in the
- // event that the iteration had to return because of finding an
- // uninitialized object in the space, or if the closure "cl"
- // signaled early termination.
- HeapWord* object_iterate_careful(ObjectClosureCareful* cl);
HeapWord* concurrent_iteration_safe_limit() {
assert(_concurrent_iteration_safe_limit <= top(),
"_concurrent_iteration_safe_limit update missed");
@@ -608,10 +586,6 @@
_concurrent_iteration_safe_limit = new_limit;
}
- // In support of parallel oop_iterate.
- template <typename OopClosureType>
- void par_oop_iterate(MemRegion mr, OopClosureType* blk);
-
// Compaction support
virtual void reset_after_compaction() {
assert(compaction_top() >= bottom() && compaction_top() <= end(), "should point inside space");
--- a/src/hotspot/share/gc/shared/space.inline.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shared/space.inline.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -377,14 +377,4 @@
set_saved_mark_word(p);
}
-template <typename OopClosureType>
-void ContiguousSpace::par_oop_iterate(MemRegion mr, OopClosureType* blk) {
- HeapWord* obj_addr = mr.start();
- HeapWord* limit = mr.end();
- while (obj_addr < limit) {
- assert(oopDesc::is_oop(oop(obj_addr)), "Should be an oop");
- obj_addr += oop(obj_addr)->oop_iterate_size(blk);
- }
-}
-
#endif // SHARE_GC_SHARED_SPACE_INLINE_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1324,11 +1324,6 @@
}
}
-void ShenandoahHeap::safe_object_iterate(ObjectClosure* cl) {
- assert(SafepointSynchronize::is_at_safepoint(), "safe iteration is only available during safepoints");
- object_iterate(cl);
-}
-
void ShenandoahHeap::heap_region_iterate(ShenandoahHeapRegionClosure* blk) const {
for (size_t i = 0; i < num_regions(); i++) {
ShenandoahHeapRegion* current = get_region(i);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -547,7 +547,6 @@
// Used for native heap walkers: heap dumpers, mostly
void object_iterate(ObjectClosure* cl);
- void safe_object_iterate(ObjectClosure* cl);
// Used by RMI
jlong millis_since_last_gc();
--- a/src/hotspot/share/gc/z/zArguments.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zArguments.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -25,7 +25,7 @@
#include "gc/z/zAddressSpaceLimit.hpp"
#include "gc/z/zArguments.hpp"
#include "gc/z/zCollectedHeap.hpp"
-#include "gc/z/zWorkers.hpp"
+#include "gc/z/zHeuristics.hpp"
#include "gc/shared/gcArguments.hpp"
#include "runtime/globals.hpp"
#include "runtime/globals_extension.hpp"
@@ -59,7 +59,7 @@
// Select number of parallel threads
if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
- FLAG_SET_DEFAULT(ParallelGCThreads, ZWorkers::calculate_nparallel());
+ FLAG_SET_DEFAULT(ParallelGCThreads, ZHeuristics::nparallel_workers());
}
if (ParallelGCThreads == 0) {
@@ -68,7 +68,7 @@
// Select number of concurrent threads
if (FLAG_IS_DEFAULT(ConcGCThreads)) {
- FLAG_SET_DEFAULT(ConcGCThreads, ZWorkers::calculate_nconcurrent());
+ FLAG_SET_DEFAULT(ConcGCThreads, ZHeuristics::nconcurrent_workers());
}
if (ConcGCThreads == 0) {
--- a/src/hotspot/share/gc/z/zCollectedHeap.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -246,10 +246,6 @@
_heap.object_iterate(cl, true /* visit_weaks */);
}
-void ZCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
- _heap.object_iterate(cl, true /* visit_weaks */);
-}
-
void ZCollectedHeap::register_nmethod(nmethod* nm) {
ZNMethod::register_nmethod(nm);
}
--- a/src/hotspot/share/gc/z/zCollectedHeap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -98,7 +98,6 @@
virtual GrowableArray<MemoryPool*> memory_pools();
virtual void object_iterate(ObjectClosure* cl);
- virtual void safe_object_iterate(ObjectClosure* cl);
virtual void register_nmethod(nmethod* nm);
virtual void unregister_nmethod(nmethod* nm);
--- a/src/hotspot/share/gc/z/zDirector.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zDirector.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -75,7 +75,7 @@
// duration, which is needed by the other rules.
const size_t max_capacity = ZHeap::heap()->soft_max_capacity();
const size_t used = ZHeap::heap()->used();
- const double used_threshold_percent = (ZStatCycle::ncycles() + 1) * 0.1;
+ const double used_threshold_percent = (ZStatCycle::nwarmup_cycles() + 1) * 0.1;
const size_t used_threshold = max_capacity * used_threshold_percent;
log_debug(gc, director)("Rule: Warmup %.0f%%, Used: " SIZE_FORMAT "MB, UsedThreshold: " SIZE_FORMAT "MB",
@@ -85,7 +85,7 @@
}
bool ZDirector::rule_allocation_rate() const {
- if (ZStatCycle::is_first()) {
+ if (!ZStatCycle::is_normalized_duration_trustable()) {
// Rule disabled
return false;
}
--- a/src/hotspot/share/gc/z/zDriver.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zDriver.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -250,17 +250,11 @@
case GCCause::_z_allocation_stall:
case GCCause::_z_proactive:
case GCCause::_z_high_usage:
+ case GCCause::_metadata_GC_threshold:
// Start asynchronous GC
_gc_cycle_port.send_async(cause);
break;
- case GCCause::_metadata_GC_threshold:
- // Start asynchronous GC, but only if the GC is warm
- if (ZStatCycle::is_warm()) {
- _gc_cycle_port.send_async(cause);
- }
- break;
-
case GCCause::_gc_locker:
// Restart VM operation previously blocked by the GC locker
_gc_locker_port.signal();
@@ -352,13 +346,15 @@
class ZDriverGCScope : public StackObj {
private:
- GCIdMark _gc_id;
- GCCauseSetter _gc_cause_setter;
- ZStatTimer _timer;
+ GCIdMark _gc_id;
+ GCCause::Cause _gc_cause;
+ GCCauseSetter _gc_cause_setter;
+ ZStatTimer _timer;
public:
ZDriverGCScope(GCCause::Cause cause) :
_gc_id(),
+ _gc_cause(cause),
_gc_cause_setter(ZCollectedHeap::heap(), cause),
_timer(ZPhaseCycle) {
// Update statistics
@@ -371,7 +367,7 @@
(double)ZHeap::heap()->nconcurrent_no_boost_worker_threads();
// Update statistics
- ZStatCycle::at_end(boost_factor);
+ ZStatCycle::at_end(_gc_cause, boost_factor);
// Update data used by soft reference policy
Universe::update_heap_info_at_gc();
--- a/src/hotspot/share/gc/z/zGlobals.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zGlobals.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -24,27 +24,35 @@
#include "precompiled.hpp"
#include "gc/z/zGlobals.hpp"
-uint32_t ZGlobalPhase = ZPhaseRelocate;
-uint32_t ZGlobalSeqNum = 1;
+uint32_t ZGlobalPhase = ZPhaseRelocate;
+uint32_t ZGlobalSeqNum = 1;
-const int& ZObjectAlignmentSmallShift = LogMinObjAlignmentInBytes;
-const int& ZObjectAlignmentSmall = MinObjAlignmentInBytes;
+size_t ZPageSizeMediumShift;
+size_t ZPageSizeMedium;
-uintptr_t ZAddressGoodMask;
-uintptr_t ZAddressBadMask;
-uintptr_t ZAddressWeakBadMask;
+size_t ZObjectSizeLimitMedium;
-uintptr_t ZAddressBase;
+const int& ZObjectAlignmentSmallShift = LogMinObjAlignmentInBytes;
+int ZObjectAlignmentMediumShift;
+
+const int& ZObjectAlignmentSmall = MinObjAlignmentInBytes;
+int ZObjectAlignmentMedium;
-size_t ZAddressOffsetBits;
-uintptr_t ZAddressOffsetMask;
-size_t ZAddressOffsetMax;
+uintptr_t ZAddressGoodMask;
+uintptr_t ZAddressBadMask;
+uintptr_t ZAddressWeakBadMask;
+
+uintptr_t ZAddressBase;
-size_t ZAddressMetadataShift;
-uintptr_t ZAddressMetadataMask;
+size_t ZAddressOffsetBits;
+uintptr_t ZAddressOffsetMask;
+size_t ZAddressOffsetMax;
-uintptr_t ZAddressMetadataMarked;
-uintptr_t ZAddressMetadataMarked0;
-uintptr_t ZAddressMetadataMarked1;
-uintptr_t ZAddressMetadataRemapped;
-uintptr_t ZAddressMetadataFinalizable;
+size_t ZAddressMetadataShift;
+uintptr_t ZAddressMetadataMask;
+
+uintptr_t ZAddressMetadataMarked;
+uintptr_t ZAddressMetadataMarked0;
+uintptr_t ZAddressMetadataMarked1;
+uintptr_t ZAddressMetadataRemapped;
+uintptr_t ZAddressMetadataFinalizable;
--- a/src/hotspot/share/gc/z/zGlobals.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zGlobals.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -50,17 +50,6 @@
// Virtual memory to physical memory ratio
const size_t ZVirtualToPhysicalRatio = 16; // 16:1
-//
-// Page Tiers (assuming ZGranuleSize=2M)
-// -------------------------------------
-//
-// Page Size Object Size Object Alignment
-// --------------------------------------------------
-// Small 2M <= 265K MinObjAlignmentInBytes
-// Medium 32M <= 4M 4K
-// Large N x 2M > 4M 2M
-//
-
// Page types
const uint8_t ZPageTypeSmall = 0;
const uint8_t ZPageTypeMedium = 1;
@@ -68,24 +57,24 @@
// Page size shifts
const size_t ZPageSizeSmallShift = ZGranuleSizeShift;
-const size_t ZPageSizeMediumShift = ZPageSizeSmallShift + 4;
+extern size_t ZPageSizeMediumShift;
// Page sizes
const size_t ZPageSizeSmall = (size_t)1 << ZPageSizeSmallShift;
-const size_t ZPageSizeMedium = (size_t)1 << ZPageSizeMediumShift;
+extern size_t ZPageSizeMedium;
// Object size limits
-const size_t ZObjectSizeLimitSmall = (ZPageSizeSmall / 8); // Allow 12.5% waste
-const size_t ZObjectSizeLimitMedium = (ZPageSizeMedium / 8); // Allow 12.5% waste
+const size_t ZObjectSizeLimitSmall = ZPageSizeSmall / 8; // 12.5% max waste
+extern size_t ZObjectSizeLimitMedium;
// Object alignment shifts
extern const int& ZObjectAlignmentSmallShift;
-const int ZObjectAlignmentMediumShift = ZPageSizeMediumShift - 13; // 8192 objects per page
-const int ZObjectAlignmentLargeShift = ZPageSizeSmallShift;
+extern int ZObjectAlignmentMediumShift;
+const int ZObjectAlignmentLargeShift = ZGranuleSizeShift;
// Object alignments
extern const int& ZObjectAlignmentSmall;
-const int ZObjectAlignmentMedium = 1 << ZObjectAlignmentMediumShift;
+extern int ZObjectAlignmentMedium;
const int ZObjectAlignmentLarge = 1 << ZObjectAlignmentLargeShift;
//
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeuristics.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zCPU.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeuristics.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "logging/log.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+
+void ZHeuristics::set_medium_page_size() {
+ // Set ZPageSizeMedium so that a medium page occupies at most 3.125% of the
+ // max heap size. ZPageSizeMedium is initially set to 0, which means medium
+ // pages are effectively disabled. It is adjusted only if ZPageSizeMedium
+ // becomes larger than ZPageSizeSmall.
+ const size_t min = ZGranuleSize;
+ const size_t max = ZGranuleSize * 16;
+ const size_t unclamped = MaxHeapSize * 0.03125;
+ const size_t clamped = MIN2(MAX2(min, unclamped), max);
+ const size_t size = ZUtils::round_down_power_of_2(clamped);
+
+ if (size > ZPageSizeSmall) {
+ // Enable medium pages
+ ZPageSizeMedium = size;
+ ZPageSizeMediumShift = log2_intptr(ZPageSizeMedium);
+ ZObjectSizeLimitMedium = ZPageSizeMedium / 8;
+ ZObjectAlignmentMediumShift = ZPageSizeMediumShift - 13;
+ ZObjectAlignmentMedium = 1 << ZObjectAlignmentMediumShift;
+
+ log_info(gc, init)("Medium Page Size: " SIZE_FORMAT "M", ZPageSizeMedium / M);
+ } else {
+ log_info(gc, init)("Medium Page Size: N/A");
+ }
+}
+
+bool ZHeuristics::use_per_cpu_shared_small_pages() {
+ // Use per-CPU shared small pages only if these pages occupy at most 3.125%
+ // of the max heap size. Otherwise fall back to using a single shared small
+ // page. This is useful when using small heaps on large machines.
+ const size_t per_cpu_share = (MaxHeapSize * 0.03125) / ZCPU::count();
+ return per_cpu_share >= ZPageSizeSmall;
+}
+
+static uint nworkers_based_on_ncpus(double cpu_share_in_percent) {
+ return ceil(os::initial_active_processor_count() * cpu_share_in_percent / 100.0);
+}
+
+static uint nworkers_based_on_heap_size(double reserve_share_in_percent) {
+ const int nworkers = (MaxHeapSize * (reserve_share_in_percent / 100.0)) / ZPageSizeSmall;
+ return MAX2(nworkers, 1);
+}
+
+static uint nworkers(double cpu_share_in_percent) {
+ // Cap number of workers so that we don't use more than 2% of the max heap
+ // for the small page reserve. This is useful when using small heaps on
+ // large machines.
+ return MIN2(nworkers_based_on_ncpus(cpu_share_in_percent),
+ nworkers_based_on_heap_size(2.0));
+}
+
+uint ZHeuristics::nparallel_workers() {
+ // Use 60% of the CPUs, rounded up. We would like to use as many threads as
+ // possible to increase parallelism. However, using a thread count that is
+ // close to the number of processors tends to lead to over-provisioning and
+ // scheduling latency issues. Using 60% of the active processors appears to
+ // be a fairly good balance.
+ return nworkers(60.0);
+}
+
+uint ZHeuristics::nconcurrent_workers() {
+ // Use 12.5% of the CPUs, rounded up. The number of concurrent threads we
+ // would like to use heavily depends on the type of workload we are running.
+ // Using too many threads will have a negative impact on the application
+ // throughput, while using too few threads will prolong the GC-cycle and
+ // we then risk being out-run by the application. Using 12.5% of the active
+ // processors appears to be a fairly good balance.
+ return nworkers(12.5);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeuristics.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZHEURISTICS_HPP
+#define SHARE_GC_Z_ZHEURISTICS_HPP
+
+#include "memory/allocation.hpp"
+
+class ZHeuristics : public AllStatic {
+public:
+ static void set_medium_page_size();
+
+ static bool use_per_cpu_shared_small_pages();
+
+ static uint nparallel_workers();
+ static uint nconcurrent_workers();
+};
+
+#endif // SHARE_GC_Z_ZHEURISTICS_HPP
--- a/src/hotspot/share/gc/z/zInitialize.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zInitialize.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -26,6 +26,7 @@
#include "gc/z/zBarrierSet.hpp"
#include "gc/z/zCPU.hpp"
#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeuristics.hpp"
#include "gc/z/zInitialize.hpp"
#include "gc/z/zLargePages.hpp"
#include "gc/z/zNUMA.hpp"
@@ -49,6 +50,7 @@
ZThreadLocalAllocBuffer::initialize();
ZTracer::initialize();
ZLargePages::initialize();
+ ZHeuristics::set_medium_page_size();
ZBarrierSet::set_barrier_set(barrier_set);
initialize_os();
--- a/src/hotspot/share/gc/z/zObjectAllocator.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zObjectAllocator.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#include "gc/z/zCollectedHeap.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zHeuristics.hpp"
#include "gc/z/zObjectAllocator.hpp"
#include "gc/z/zPage.inline.hpp"
#include "gc/z/zStat.hpp"
@@ -43,12 +44,21 @@
static const ZStatCounter ZCounterUndoObjectAllocationFailed("Memory", "Undo Object Allocation Failed", ZStatUnitOpsPerSecond);
ZObjectAllocator::ZObjectAllocator() :
+ _use_per_cpu_shared_small_pages(ZHeuristics::use_per_cpu_shared_small_pages()),
_used(0),
_undone(0),
_shared_medium_page(NULL),
_shared_small_page(NULL),
_worker_small_page(NULL) {}
+ZPage** ZObjectAllocator::shared_small_page_addr() {
+ return _use_per_cpu_shared_small_pages ? _shared_small_page.addr() : _shared_small_page.addr(0);
+}
+
+ZPage* const* ZObjectAllocator::shared_small_page_addr() const {
+ return _use_per_cpu_shared_small_pages ? _shared_small_page.addr() : _shared_small_page.addr(0);
+}
+
ZPage* ZObjectAllocator::alloc_page(uint8_t type, size_t size, ZAllocationFlags flags) {
ZPage* const page = ZHeap::heap()->alloc_page(type, size, flags);
if (page != NULL) {
@@ -72,7 +82,7 @@
size_t size,
ZAllocationFlags flags) {
uintptr_t addr = 0;
- ZPage* page = *shared_page;
+ ZPage* page = OrderAccess::load_acquire(shared_page);
if (page != NULL) {
addr = page->alloc_object_atomic(size);
@@ -142,7 +152,7 @@
// Non-worker small page allocation can never use the reserve
flags.set_no_reserve();
- return alloc_object_in_shared_page(_shared_small_page.addr(), ZPageTypeSmall, ZPageSizeSmall, size, flags);
+ return alloc_object_in_shared_page(shared_small_page_addr(), ZPageTypeSmall, ZPageSizeSmall, size, flags);
}
uintptr_t ZObjectAllocator::alloc_small_object_from_worker(size_t size, ZAllocationFlags flags) {
@@ -294,7 +304,7 @@
size_t ZObjectAllocator::remaining() const {
assert(ZThread::is_java(), "Should be a Java thread");
- ZPage* page = _shared_small_page.get();
+ const ZPage* const page = OrderAccess::load_acquire(shared_small_page_addr());
if (page != NULL) {
return page->remaining();
}
--- a/src/hotspot/share/gc/z/zObjectAllocator.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zObjectAllocator.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -31,12 +31,16 @@
class ZObjectAllocator {
private:
+ const bool _use_per_cpu_shared_small_pages;
ZPerCPU<size_t> _used;
ZPerCPU<size_t> _undone;
ZContended<ZPage*> _shared_medium_page;
ZPerCPU<ZPage*> _shared_small_page;
ZPerWorker<ZPage*> _worker_small_page;
+ ZPage** shared_small_page_addr();
+ ZPage* const* shared_small_page_addr() const;
+
ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags);
void undo_alloc_page(ZPage* page);
--- a/src/hotspot/share/gc/z/zPage.inline.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zPage.inline.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -39,14 +39,11 @@
#include "utilities/debug.hpp"
inline uint8_t ZPage::type_from_size(size_t size) const {
- switch (size) {
- case ZPageSizeSmall:
+ if (size == ZPageSizeSmall) {
return ZPageTypeSmall;
-
- case ZPageSizeMedium:
+ } else if (size == ZPageSizeMedium) {
return ZPageTypeMedium;
-
- default:
+ } else {
return ZPageTypeLarge;
}
}
--- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -97,6 +97,11 @@
}
void ZRelocationSetSelectorGroup::select() {
+ if (_page_size == 0) {
+ // Page type disabled
+ return;
+ }
+
// Calculate the number of pages to relocate by successively including pages in
// a candidate relocation set and calculate the maximum space requirement for
// their live objects.
--- a/src/hotspot/share/gc/z/zStat.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zStat.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1024,7 +1024,7 @@
//
// Stat cycle
//
-uint64_t ZStatCycle::_ncycles = 0;
+uint64_t ZStatCycle::_nwarmup_cycles = 0;
Ticks ZStatCycle::_start_of_last;
Ticks ZStatCycle::_end_of_last;
NumberSeq ZStatCycle::_normalized_duration(0.3 /* alpha */);
@@ -1033,9 +1033,12 @@
_start_of_last = Ticks::now();
}
-void ZStatCycle::at_end(double boost_factor) {
+void ZStatCycle::at_end(GCCause::Cause cause, double boost_factor) {
_end_of_last = Ticks::now();
- _ncycles++;
+
+ if (cause == GCCause::_z_warmup) {
+ _nwarmup_cycles++;
+ }
// Calculate normalized cycle duration. The measured duration is
// normalized using the boost factor to avoid artificial deflation
@@ -1045,16 +1048,18 @@
_normalized_duration.add(normalized_duration);
}
-bool ZStatCycle::is_first() {
- return _ncycles == 0;
+bool ZStatCycle::is_warm() {
+ return _nwarmup_cycles >= 3;
}
-bool ZStatCycle::is_warm() {
- return _ncycles >= 3;
+uint64_t ZStatCycle::nwarmup_cycles() {
+ return _nwarmup_cycles;
}
-uint64_t ZStatCycle::ncycles() {
- return _ncycles;
+bool ZStatCycle::is_normalized_duration_trustable() {
+ // The normalized duration is considered trustable if we have
+ // completed at least one warmup cycle
+ return _nwarmup_cycles > 0;
}
const AbsSeq& ZStatCycle::normalized_duration() {
@@ -1062,8 +1067,8 @@
}
double ZStatCycle::time_since_last() {
- if (_ncycles == 0) {
- // Return time since VM start-up
+ if (_end_of_last.value() == 0) {
+ // No end recorded yet, return time since VM start
return os::elapsedTime();
}
--- a/src/hotspot/share/gc/z/zStat.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zStat.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -25,6 +25,7 @@
#define SHARE_GC_Z_ZSTAT_HPP
#include "gc/shared/concurrentGCThread.hpp"
+#include "gc/shared/gcCause.hpp"
#include "gc/shared/gcTimer.hpp"
#include "gc/z/zMetronome.hpp"
#include "logging/logHandle.hpp"
@@ -365,19 +366,21 @@
//
class ZStatCycle : public AllStatic {
private:
- static uint64_t _ncycles;
+ static uint64_t _nwarmup_cycles;
static Ticks _start_of_last;
static Ticks _end_of_last;
static NumberSeq _normalized_duration;
public:
static void at_start();
- static void at_end(double boost_factor);
+ static void at_end(GCCause::Cause cause, double boost_factor);
- static bool is_first();
static bool is_warm();
- static uint64_t ncycles();
+ static uint64_t nwarmup_cycles();
+
+ static bool is_normalized_duration_trustable();
static const AbsSeq& normalized_duration();
+
static double time_since_last();
};
--- a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -69,7 +69,9 @@
ThreadLocalAllocStats* const stats = _stats->addr();
thread->tlab().addresses_do(fixup_address);
thread->tlab().retire(stats);
- thread->tlab().resize();
+ if (ResizeTLAB) {
+ thread->tlab().resize();
+ }
}
}
--- a/src/hotspot/share/gc/z/zWorkers.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zWorkers.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -26,45 +26,9 @@
#include "gc/z/zTask.hpp"
#include "gc/z/zThread.hpp"
#include "gc/z/zWorkers.inline.hpp"
-#include "runtime/os.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
-static uint calculate_nworkers_based_on_ncpus(double cpu_share_in_percent) {
- return ceil(os::initial_active_processor_count() * cpu_share_in_percent / 100.0);
-}
-
-static uint calculate_nworkers_based_on_heap_size(double reserve_share_in_percent) {
- const int nworkers = ((MaxHeapSize * (reserve_share_in_percent / 100.0)) - ZPageSizeMedium) / ZPageSizeSmall;
- return MAX2(nworkers, 1);
-}
-
-static uint calculate_nworkers(double cpu_share_in_percent) {
- // Cap number of workers so that we never use more than 10% of the max heap
- // for the reserve. This is useful when using small heaps on large machines.
- return MIN2(calculate_nworkers_based_on_ncpus(cpu_share_in_percent),
- calculate_nworkers_based_on_heap_size(10.0));
-}
-
-uint ZWorkers::calculate_nparallel() {
- // Use 60% of the CPUs, rounded up. We would like to use as many threads as
- // possible to increase parallelism. However, using a thread count that is
- // close to the number of processors tends to lead to over-provisioning and
- // scheduling latency issues. Using 60% of the active processors appears to
- // be a fairly good balance.
- return calculate_nworkers(60.0);
-}
-
-uint ZWorkers::calculate_nconcurrent() {
- // Use 12.5% of the CPUs, rounded up. The number of concurrent threads we
- // would like to use heavily depends on the type of workload we are running.
- // Using too many threads will have a negative impact on the application
- // throughput, while using too few threads will prolong the GC-cycle and
- // we then risk being out-run by the application. Using 12.5% of the active
- // processors appears to be a fairly good balance.
- return calculate_nworkers(12.5);
-}
-
class ZWorkersInitializeTask : public ZTask {
private:
const uint _nworkers;
--- a/src/hotspot/share/gc/z/zWorkers.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/gc/z/zWorkers.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -37,9 +37,6 @@
void run(ZTask* task, uint nworkers);
public:
- static uint calculate_nparallel();
- static uint calculate_nconcurrent();
-
ZWorkers();
uint nparallel() const;
--- a/src/hotspot/share/interpreter/abstractInterpreter.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -222,6 +222,7 @@
CodeBuffer buffer(trampoline, (int)(SharedRuntime::trampoline_size()));
MacroAssembler _masm(&buffer);
SharedRuntime::generate_trampoline(&_masm, _entry_table[kind]);
+ _masm.flush();
if (PrintInterpreter) {
Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
--- a/src/hotspot/share/memory/freeList.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/memory/freeList.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -39,7 +39,6 @@
template <class Chunk_t>
class FreeList {
- friend class CompactibleFreeListSpace;
friend class VMStructs;
private:
--- a/src/hotspot/share/memory/heap.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/memory/heap.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -45,6 +45,7 @@
_log2_segment_size = 0;
_next_segment = 0;
_freelist = NULL;
+ _last_insert_point = NULL;
_freelist_segments = 0;
_freelist_length = 0;
_max_allocated_capacity = 0;
@@ -52,11 +53,24 @@
_nmethod_count = 0;
_adapter_count = 0;
_full_count = 0;
+ _fragmentation_count = 0;
}
+// Dummy initialization of template array.
+char CodeHeap::segmap_template[] = {0};
+
+// This template array is used to (re)initialize the segmap,
+// replacing a 1..254 loop.
+void CodeHeap::init_segmap_template() {
+ assert(free_sentinel == 255, "Segment map logic changed!");
+ for (int i = 0; i <= free_sentinel; i++) {
+ segmap_template[i] = i;
+ }
+}
// The segmap is marked free for that part of the heap
// which has not been allocated yet (beyond _next_segment).
+// The range of segments to be marked is given by [beg..end).
// "Allocated" space in this context means there exists a
// HeapBlock or a FreeBlock describing this space.
// This method takes segment map indices as range boundaries
@@ -78,8 +92,9 @@
// have their segmap marked as used. This allows to find the
// block header (HeapBlock or FreeBlock) for any pointer
// within the allocated range (upper limit: _next_segment).
-// This method takes segment map indices as range boundaries
-void CodeHeap::mark_segmap_as_used(size_t beg, size_t end) {
+// This method takes segment map indices as range boundaries.
+// The range of segments to be marked is given by [beg..end).
+void CodeHeap::mark_segmap_as_used(size_t beg, size_t end, bool is_FreeBlock_join) {
assert( beg < _number_of_committed_segments, "interval begin out of bounds");
assert(beg < end && end <= _number_of_committed_segments, "interval end out of bounds");
// Don't do unpredictable things in PRODUCT build
@@ -88,10 +103,63 @@
address p = (address)_segmap.low() + beg;
address q = (address)_segmap.low() + end;
// initialize interval
- int i = 0;
- while (p < q) {
- *p++ = i++;
- if (i == free_sentinel) i = 1;
+ // If we are joining two free blocks, the segmap range for each
+ // block is consistent. To create a consistent segmap range for
+ // the blocks combined, we have three choices:
+ // 1 - Do a full init from beg to end. Not very efficient because
+ // the segmap range for the left block is potentially initialized
+ // over and over again.
+ // 2 - Carry over the last segmap element value of the left block
+ // and initialize the segmap range of the right block starting
+ // with that value. Saves initializing the left block's segmap
+ // over and over again. Very efficient if FreeBlocks mostly
+ // are appended to the right.
+ // 3 - Take full advantage of the segmap being almost correct with
+ // the two blocks combined. Lets assume the left block consists
+ // of m segments. The the segmap looks like
+ // ... (m-2) (m-1) (m) 0 1 2 3 ...
+ // By substituting the '0' by '1', we create a valid, but
+ // suboptimal, segmap range covering the two blocks combined.
+ // We introduced an extra hop for the find_block_for() iteration.
+ //
+ // When this method is called with is_FreeBlock_join == true, the
+ // segmap index beg must select the first segment of the right block.
+ // Otherwise, it has to select the first segment of the left block.
+ // Variant 3 is used for all FreeBlock joins.
+ if (is_FreeBlock_join && (beg > 0)) {
+#ifndef PRODUCT
+ FreeBlock* pBlock = (FreeBlock*)block_at(beg);
+ assert(beg + pBlock->length() == end, "Internal error: (%d - %d) != %d", (unsigned int)end, (unsigned int)beg, (unsigned int)(pBlock->length()));
+ assert(*p == 0, "Begin index does not select a block start segment, *p = %2.2x", *p);
+#endif
+ // If possible, extend the previous hop.
+ if (*(p-1) < (free_sentinel-1)) {
+ *p = *(p-1) + 1;
+ } else {
+ *p = 1;
+ }
+ if (_fragmentation_count++ >= fragmentation_limit) {
+ defrag_segmap(true);
+ _fragmentation_count = 0;
+ }
+ } else {
+ size_t n_bulk = free_sentinel-1; // bulk processing uses template indices [1..254].
+ // Use shortcut for blocks <= 255 segments.
+ // Special case bulk processing: [0..254].
+ if ((end - beg) <= n_bulk) {
+ memcpy(p, &segmap_template[0], end - beg);
+ } else {
+ *p++ = 0; // block header marker
+ while (p < q) {
+ if ((p+n_bulk) <= q) {
+ memcpy(p, &segmap_template[1], n_bulk);
+ p += n_bulk;
+ } else {
+ memcpy(p, &segmap_template[1], q-p);
+ p = q;
+ }
+ }
+ }
}
}
}
@@ -178,6 +246,7 @@
// initialize remaining instance variables, heap memory and segmap
clear();
+ init_segmap_template();
return true;
}
@@ -220,14 +289,11 @@
NOT_PRODUCT(verify());
if (block != NULL) {
- assert(!block->free(), "must be marked free");
+ assert(!block->free(), "must not be marked free");
guarantee((char*) block >= _memory.low_boundary() && (char*) block < _memory.high(),
"The newly allocated block " INTPTR_FORMAT " is not within the heap "
"starting with " INTPTR_FORMAT " and ending with " INTPTR_FORMAT,
p2i(block), p2i(_memory.low_boundary()), p2i(_memory.high()));
- // Invalidate the additional space that FreeBlock occupies. The rest of the block should already be invalidated.
- // This is necessary due to a dubious assert in nmethod.cpp(PcDescCache::reset_to()).
- DEBUG_ONLY(memset((void*)block->allocated_space(), badCodeHeapNewVal, sizeof(FreeBlock) - sizeof(HeapBlock)));
_max_allocated_capacity = MAX2(_max_allocated_capacity, allocated_capacity());
_blob_count++;
return block->allocated_space();
@@ -237,17 +303,17 @@
number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments);
if (_next_segment + number_of_segments <= _number_of_committed_segments) {
- mark_segmap_as_used(_next_segment, _next_segment + number_of_segments);
- HeapBlock* b = block_at(_next_segment);
- b->initialize(number_of_segments);
+ mark_segmap_as_used(_next_segment, _next_segment + number_of_segments, false);
+ block = block_at(_next_segment);
+ block->initialize(number_of_segments);
_next_segment += number_of_segments;
- guarantee((char*) b >= _memory.low_boundary() && (char*) block < _memory.high(),
+ guarantee((char*) block >= _memory.low_boundary() && (char*) block < _memory.high(),
"The newly allocated block " INTPTR_FORMAT " is not within the heap "
"starting with " INTPTR_FORMAT " and ending with " INTPTR_FORMAT,
- p2i(b), p2i(_memory.low_boundary()), p2i(_memory.high()));
+ p2i(block), p2i(_memory.low_boundary()), p2i(_memory.high()));
_max_allocated_capacity = MAX2(_max_allocated_capacity, allocated_capacity());
_blob_count++;
- return b->allocated_space();
+ return block->allocated_space();
} else {
return NULL;
}
@@ -273,7 +339,7 @@
HeapBlock* newb = block_at(split_segment);
newb->set_length(newb_size);
- mark_segmap_as_used(segment_for(newb), segment_for(newb) + newb_size);
+ mark_segmap_as_used(segment_for(newb), segment_for(newb) + newb_size, false);
b->set_length(split_at);
return newb;
}
@@ -308,61 +374,117 @@
}
/**
- * Uses segment map to find the the start (header) of a nmethod. This works as follows:
- * The memory of the code cache is divided into 'segments'. The size of a segment is
- * determined by -XX:CodeCacheSegmentSize=XX. Allocation in the code cache can only
- * happen at segment boundaries. A pointer in the code cache can be mapped to a segment
- * by calling segment_for(addr). Each time memory is requested from the code cache,
- * the segmap is updated accordingly. See the following example, which illustrates the
- * state of code cache and the segment map: (seg -> segment, nm ->nmethod)
+ * The segment map is used to quickly find the the start (header) of a
+ * code block (e.g. nmethod) when only a pointer to a location inside the
+ * code block is known. This works as follows:
+ * - The storage reserved for the code heap is divided into 'segments'.
+ * - The size of a segment is determined by -XX:CodeCacheSegmentSize=<#bytes>.
+ * - The size must be a power of two to allow the use of shift operations
+ * to quickly convert between segment index and segment address.
+ * - Segment start addresses should be aligned to be multiples of CodeCacheSegmentSize.
+ * - It seems beneficial for CodeCacheSegmentSize to be equal to os::page_size().
+ * - Allocation in the code cache can only happen at segment start addresses.
+ * - Allocation in the code cache is in units of CodeCacheSegmentSize.
+ * - A pointer in the code cache can be mapped to a segment by calling
+ * segment_for(addr).
+ * - The segment map is a byte array where array element [i] is related
+ * to the i-th segment in the code heap.
+ * - Each time memory is allocated/deallocated from the code cache,
+ * the segment map is updated accordingly.
+ * Note: deallocation does not cause the memory to become "free", as
+ * indicated by the segment map state "free_sentinel". Deallocation
+ * just changes the block state from "used" to "free".
+ * - Elements of the segment map (byte) array are interpreted
+ * as unsigned integer.
+ * - Element values normally identify an offset backwards (in segment
+ * size units) from the associated segment towards the start of
+ * the block.
+ * - Some values have a special meaning:
+ * 0 - This segment is the start of a block (HeapBlock or FreeBlock).
+ * 255 - The free_sentinel value. This is a free segment, i.e. it is
+ * not yet allocated and thus does not belong to any block.
+ * - The value of the current element has to be subtracted from the
+ * current index to get closer to the start.
+ * - If the value of the then current element is zero, the block start
+ * segment is found and iteration stops. Otherwise, start over with the
+ * previous step.
+ *
+ * The following example illustrates a possible state of code cache
+ * and the segment map: (seg -> segment, nm ->nmethod)
*
* code cache segmap
* ----------- ---------
* seg 1 | nm 1 | -> | 0 |
* seg 2 | nm 1 | -> | 1 |
* ... | nm 1 | -> | .. |
+ * seg m-1 | nm 1 | -> | m-1 |
* seg m | nm 2 | -> | 0 |
* seg m+1 | nm 2 | -> | 1 |
* ... | nm 2 | -> | 2 |
* ... | nm 2 | -> | .. |
- * ... | nm 2 | -> | 0xFE |
- * seg m+n | nm 2 | -> | 1 |
+ * ... | nm 2 | -> | 0xFE | (free_sentinel-1)
+ * ... | nm 2 | -> | 1 |
+ * seg m+n | nm 2 | -> | 2 |
* ... | nm 2 | -> | |
*
- * A value of '0' in the segmap indicates that this segment contains the beginning of
- * an nmethod. Let's walk through a simple example: If we want to find the start of
- * an nmethod that falls into seg 2, we read the value of the segmap[2]. The value
- * is an offset that points to the segment that contains the start of the nmethod.
- * Another example: If we want to get the start of nm 2, and we happen to get a pointer
- * that points to seg m+n, we first read seg[n+m], which returns '1'. So we have to
- * do one more read of the segmap[m+n-1] to finally get the segment header.
+ * How to read:
+ * A value of '0' in the segmap indicates that this segment contains the
+ * beginning of a CodeHeap block. Let's walk through a simple example:
+ *
+ * We want to find the start of the block that contains nm 1, and we are
+ * given a pointer that points into segment m-2. We then read the value
+ * of segmap[m-2]. The value is an offset that points to the segment
+ * which contains the start of the block.
+ *
+ * Another example: We want to locate the start of nm 2, and we happen to
+ * get a pointer that points into seg m+n. We first read seg[n+m], which
+ * returns '2'. So we have to update our segment map index (ix -= segmap[n+m])
+ * and start over.
*/
-void* CodeHeap::find_start(void* p) const {
+
+// Find block which contains the passed pointer,
+// regardless of the block being used or free.
+// NULL is returned if anything invalid is detected.
+void* CodeHeap::find_block_for(void* p) const {
+ // Check the pointer to be in committed range.
if (!contains(p)) {
return NULL;
}
- size_t seg_idx = segment_for(p);
+
address seg_map = (address)_segmap.low();
+ size_t seg_idx = segment_for(p);
+
+ // This may happen in special cases. Just ignore.
+ // Example: PPC ICache stub generation.
if (is_segment_unused(seg_map[seg_idx])) {
return NULL;
}
+
+ // Iterate the segment map chain to find the start of the block.
while (seg_map[seg_idx] > 0) {
+ // Don't check each segment index to refer to a used segment.
+ // This method is called extremely often. Therefore, any checking
+ // has a significant impact on performance. Rely on CodeHeap::verify()
+ // to do the job on request.
seg_idx -= (int)seg_map[seg_idx];
}
- HeapBlock* h = block_at(seg_idx);
- if (h->free()) {
- return NULL;
- }
- return h->allocated_space();
+ return address_for(seg_idx);
}
+// Find block which contains the passed pointer.
+// The block must be used, i.e. must not be a FreeBlock.
+// Return a pointer that points past the block header.
+void* CodeHeap::find_start(void* p) const {
+ HeapBlock* h = (HeapBlock*)find_block_for(p);
+ return ((h == NULL) || h->free()) ? NULL : h->allocated_space();
+}
+
+// Find block which contains the passed pointer.
+// Same as find_start(p), but with additional safety net.
CodeBlob* CodeHeap::find_blob_unsafe(void* start) const {
CodeBlob* result = (CodeBlob*)CodeHeap::find_start(start);
- if (result != NULL && result->blob_contains((address)start)) {
- return result;
- }
- return NULL;
+ return (result != NULL && result->blob_contains((address)start)) ? result : NULL;
}
size_t CodeHeap::alignment_unit() const {
@@ -382,6 +504,7 @@
// Free blocks are merged, therefore there is at most one free block
// between two used ones. As a result, the subsequent block (if available) is
// guaranteed to be used.
+// The returned pointer points past the block header.
void* CodeHeap::next_used(HeapBlock* b) const {
if (b != NULL && b->free()) b = next_block(b);
assert(b == NULL || !b->free(), "must be in use or at end of heap");
@@ -389,19 +512,22 @@
}
// Returns the first used HeapBlock
+// The returned pointer points to the block header.
HeapBlock* CodeHeap::first_block() const {
if (_next_segment > 0)
return block_at(0);
return NULL;
}
+// The returned pointer points to the block header.
HeapBlock* CodeHeap::block_start(void* q) const {
HeapBlock* b = (HeapBlock*)find_start(q);
if (b == NULL) return NULL;
return b - 1;
}
-// Returns the next Heap block an offset into one
+// Returns the next Heap block.
+// The returned pointer points to the block header.
HeapBlock* CodeHeap::next_block(HeapBlock *b) const {
if (b == NULL) return NULL;
size_t i = segment_for(b) + b->length();
@@ -459,13 +585,20 @@
assert(a->free(), "must be a free block");
if (following_block(a) == a->link()) {
assert(a->link() != NULL && a->link()->free(), "must be free too");
- // Update block a to include the following block
+
+ // Remember linked (following) block. invalidate should only zap header of this block.
+ size_t follower = segment_for(a->link());
+ // Merge block a to include the following block.
a->set_length(a->length() + a->link()->length());
a->set_link(a->link()->link());
- // Update find_start map
- size_t beg = segment_for(a);
- mark_segmap_as_used(beg, beg + a->length());
- invalidate(beg, beg + a->length(), sizeof(FreeBlock));
+
+ // Update the segment map and invalidate block contents.
+ mark_segmap_as_used(follower, segment_for(a) + a->length(), true);
+ // Block contents has already been invalidated by add_to_freelist.
+ // What's left is the header of the following block which now is
+ // in the middle of the merged block. Just zap one segment.
+ invalidate(follower, follower + 1, 0);
+
_freelist_length--;
return true;
}
@@ -503,10 +636,17 @@
return;
}
- // Scan for right place to put into list. List
- // is sorted by increasing addresses
+ // Scan for right place to put into list.
+ // List is sorted by increasing addresses.
FreeBlock* prev = _freelist;
FreeBlock* cur = _freelist->link();
+ if ((_freelist_length > freelist_limit) && (_last_insert_point != NULL)) {
+ _last_insert_point = (FreeBlock*)find_block_for(_last_insert_point);
+ if ((_last_insert_point != NULL) && _last_insert_point->free() && (_last_insert_point < b)) {
+ prev = _last_insert_point;
+ cur = prev->link();
+ }
+ }
while(cur != NULL && cur < b) {
assert(prev < cur, "Freelist must be ordered");
prev = cur;
@@ -514,6 +654,7 @@
}
assert((prev < b) && (cur == NULL || b < cur), "free-list must be ordered");
insert_after(prev, b);
+ _last_insert_point = prev;
}
/**
@@ -569,7 +710,13 @@
// Unmap element
found_prev->set_link(found_block->link());
}
- res = found_block;
+ res = (HeapBlock*)found_block;
+ // sizeof(HeapBlock) < sizeof(FreeBlock).
+ // Invalidate the additional space that FreeBlock occupies.
+ // The rest of the block should already be invalidated.
+ // This is necessary due to a dubious assert in nmethod.cpp(PcDescCache::reset_to()).
+ // Can't use invalidate() here because it works on segment_size units (too coarse).
+ DEBUG_ONLY(memset((void*)res->allocated_space(), badCodeHeapNewVal, sizeof(FreeBlock) - sizeof(HeapBlock)));
} else {
// Truncate the free block and return the truncated part
// as new HeapBlock. The remaining free block does not
@@ -583,6 +730,51 @@
return res;
}
+int CodeHeap::defrag_segmap(bool do_defrag) {
+ int extra_hops_used = 0;
+ int extra_hops_free = 0;
+ int blocks_used = 0;
+ int blocks_free = 0;
+ for(HeapBlock* h = first_block(); h != NULL; h = next_block(h)) {
+ size_t beg = segment_for(h);
+ size_t end = segment_for(h) + h->length();
+ int extra_hops = segmap_hops(beg, end);
+ if (h->free()) {
+ extra_hops_free += extra_hops;
+ blocks_free++;
+ } else {
+ extra_hops_used += extra_hops;
+ blocks_used++;
+ }
+ if (do_defrag && (extra_hops > 0)) {
+ mark_segmap_as_used(beg, end, false);
+ }
+ }
+ return extra_hops_used + extra_hops_free;
+}
+
+// Count the hops required to get from the last segment of a
+// heap block to the block header segment. For the optimal case,
+// #hops = ((#segments-1)+(free_sentinel-2))/(free_sentinel-1)
+// The range of segments to be checked is given by [beg..end).
+// Return the number of extra hops required. There may be extra hops
+// due to the is_FreeBlock_join optimization in mark_segmap_as_used().
+int CodeHeap::segmap_hops(size_t beg, size_t end) {
+ if (beg < end) {
+ // setup _segmap pointers for faster indexing
+ address p = (address)_segmap.low() + beg;
+ int hops_expected = (int)(((end-beg-1)+(free_sentinel-2))/(free_sentinel-1));
+ int nhops = 0;
+ size_t ix = end-beg-1;
+ while (p[ix] > 0) {
+ ix -= p[ix];
+ nhops++;
+ }
+ return (nhops > hops_expected) ? nhops - hops_expected : 0;
+ }
+ return 0;
+}
+
//----------------------------------------------------------------------------
// Non-product code
@@ -619,20 +811,26 @@
}
}
- // Verify segment map marking.
- // All allocated segments, no matter if in a free or used block,
- // must be marked "in use".
address seg_map = (address)_segmap.low();
- size_t nseg = 0;
+ size_t nseg = 0;
+ int extra_hops = 0;
+ count = 0;
for(HeapBlock* b = first_block(); b != NULL; b = next_block(b)) {
size_t seg1 = segment_for(b);
size_t segn = seg1 + b->length();
+ extra_hops += segmap_hops(seg1, segn);
+ count++;
for (size_t i = seg1; i < segn; i++) {
nseg++;
- assert(!is_segment_unused(seg_map[i]), "CodeHeap: unused segment. %d [%d..%d], %s block", (int)i, (int)seg1, (int)segn, b->free()? "free":"used");
+ //---< Verify segment map marking >---
+ // All allocated segments, no matter if in a free or used block,
+ // must be marked "in use".
+ assert(!is_segment_unused(seg_map[i]), "CodeHeap: unused segment. seg_map[%d]([%d..%d]) = %d, %s block", (int)i, (int)seg1, (int)segn, seg_map[i], b->free()? "free":"used");
+ assert((unsigned char)seg_map[i] < free_sentinel, "CodeHeap: seg_map[%d]([%d..%d]) = %d (out of range)", (int)i, (int)seg1, (int)segn, seg_map[i]);
}
}
assert(nseg == _next_segment, "CodeHeap: segment count mismatch. found %d, expected %d.", (int)nseg, (int)_next_segment);
+ assert((count == 0) || (extra_hops < (16 + 2*count)), "CodeHeap: many extra hops due to optimization. blocks: %d, extra hops: %d.", count, extra_hops);
// Verify that the number of free blocks is not out of hand.
static int free_block_threshold = 10000;
--- a/src/hotspot/share/memory/heap.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/memory/heap.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -92,6 +92,7 @@
size_t _next_segment;
FreeBlock* _freelist;
+ FreeBlock* _last_insert_point; // last insert point in add_to_freelist
size_t _freelist_segments; // No. of segments in freelist
int _freelist_length;
size_t _max_allocated_capacity; // Peak capacity that was allocated during lifetime of the heap
@@ -102,9 +103,12 @@
int _nmethod_count; // Number of nmethods
int _adapter_count; // Number of adapters
int _full_count; // Number of times the code heap was full
-
+ int _fragmentation_count; // #FreeBlock joins without fully initializing segment map elements.
enum { free_sentinel = 0xFF };
+ static const int fragmentation_limit = 10000; // defragment after that many potential fragmentations.
+ static const int freelist_limit = 100; // improve insert point search if list is longer than this limit.
+ static char segmap_template[free_sentinel+1];
// Helper functions
size_t size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; }
@@ -112,14 +116,17 @@
size_t segment_for(void* p) const { return ((char*)p - _memory.low()) >> _log2_segment_size; }
bool is_segment_unused(int val) const { return val == free_sentinel; }
- HeapBlock* block_at(size_t i) const { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
+ void* address_for(size_t i) const { return (void*)(_memory.low() + segments_to_size(i)); }
+ void* find_block_for(void* p) const;
+ HeapBlock* block_at(size_t i) const { return (HeapBlock*)address_for(i); }
// These methods take segment map indices as range boundaries
void mark_segmap_as_free(size_t beg, size_t end);
- void mark_segmap_as_used(size_t beg, size_t end);
+ void mark_segmap_as_used(size_t beg, size_t end, bool is_FreeBlock_join);
void invalidate(size_t beg, size_t end, size_t header_bytes);
void clear(size_t beg, size_t end);
void clear(); // clears all heap contents
+ static void init_segmap_template();
// Freelist management helpers
FreeBlock* following_block(FreeBlock* b);
@@ -154,12 +161,15 @@
// beforehand and we also can't easily relocate the interpreter to a new location.
void deallocate_tail(void* p, size_t used_size);
- // Attributes
+ // Boundaries of committed space.
+ char* low() const { return _memory.low(); }
+ char* high() const { return _memory.high(); }
+ // Boundaries of reserved space.
char* low_boundary() const { return _memory.low_boundary(); }
- char* high() const { return _memory.high(); }
char* high_boundary() const { return _memory.high_boundary(); }
- bool contains(const void* p) const { return low_boundary() <= p && p < high(); }
+ // Containment means "contained in committed space".
+ bool contains(const void* p) const { return low() <= p && p < high(); }
bool contains_blob(const CodeBlob* blob) const {
// AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap.
// Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated
@@ -219,6 +229,8 @@
private:
size_t heap_unallocated_capacity() const;
+ int defrag_segmap(bool do_defrag);
+ int segmap_hops(size_t beg, size_t end);
public:
// Debugging
--- a/src/hotspot/share/memory/heapInspection.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/memory/heapInspection.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -719,7 +719,7 @@
ResourceMark rm;
RecordInstanceClosure ric(cit, filter);
- Universe::heap()->safe_object_iterate(&ric);
+ Universe::heap()->object_iterate(&ric);
return ric.missed_count();
}
@@ -792,5 +792,5 @@
// Iterate over objects in the heap
FindInstanceClosure fic(k, result);
- Universe::heap()->safe_object_iterate(&fic);
+ Universe::heap()->object_iterate(&fic);
}
--- a/src/hotspot/share/memory/iterator.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/memory/iterator.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -199,34 +199,6 @@
ObjectToOopClosure(OopIterateClosure* cl) : _cl(cl) {}
};
-// A version of ObjectClosure that is expected to be robust
-// in the face of possibly uninitialized objects.
-class ObjectClosureCareful : public ObjectClosure {
- public:
- virtual size_t do_object_careful_m(oop p, MemRegion mr) = 0;
- virtual size_t do_object_careful(oop p) = 0;
-};
-
-// The following are used in CompactibleFreeListSpace and
-// ConcurrentMarkSweepGeneration.
-
-// Blk closure (abstract class)
-class BlkClosure : public StackObj {
- public:
- virtual size_t do_blk(HeapWord* addr) = 0;
-};
-
-// A version of BlkClosure that is expected to be robust
-// in the face of possibly uninitialized objects.
-class BlkClosureCareful : public BlkClosure {
- public:
- size_t do_blk(HeapWord* addr) {
- guarantee(false, "call do_blk_careful instead");
- return 0;
- }
- virtual size_t do_blk_careful(HeapWord* addr) = 0;
-};
-
// SpaceClosure is used for iterating over spaces
class Space;
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1271,9 +1271,6 @@
}
// do the iteration
- // If this operation encounters a bad object when using CMS,
- // consider using safe_object_iterate() which avoids perm gen
- // objects that may contain bad references.
Universe::heap()->object_iterate(_blk);
}
--- a/src/hotspot/share/runtime/mutex.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/mutex.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -288,8 +288,6 @@
assert(_safepoint_check_required != _safepoint_check_sometimes || is_sometimes_ok(name),
"Lock has _safepoint_check_sometimes %s", name);
- assert(_rank > special || _allow_vm_block,
- "Special locks or below should allow the vm to block");
assert(_rank > special || _safepoint_check_required == _safepoint_check_never,
"Special locks or below should never safepoint");
#endif
--- a/src/hotspot/share/runtime/objectMonitor.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -26,6 +26,8 @@
#include "classfile/vmSymbols.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/support/jfrThreadId.hpp"
+#include "logging/log.hpp"
+#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/markWord.hpp"
@@ -255,7 +257,7 @@
return;
}
- if (Self->is_lock_owned ((address)cur)) {
+ if (Self->is_lock_owned((address)cur)) {
assert(_recursions == 0, "internal state error");
_recursions = 1;
// Commute owner from a thread-specific on-stack BasicLockObject address to
@@ -275,8 +277,7 @@
// we forgo posting JVMTI events and firing DTRACE probes.
if (TrySpin(Self) > 0) {
assert(_owner == Self, "must be Self: owner=" INTPTR_FORMAT, p2i(_owner));
- assert(_recursions == 0, "must be 0: recursions=" INTPTR_FORMAT,
- _recursions);
+ assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions);
assert(((oop)object())->mark() == markWord::encode(this),
"object mark must match encoded this: mark=" INTPTR_FORMAT
", encoded this=" INTPTR_FORMAT, ((oop)object())->mark().value(),
@@ -881,7 +882,14 @@
// way we should encounter this situation is in the presence of
// unbalanced JNI locking. TODO: CheckJNICalls.
// See also: CR4414101
- assert(false, "Non-balanced monitor enter/exit! Likely JNI locking");
+#ifdef ASSERT
+ LogStreamHandle(Error, monitorinflation) lsh;
+ lsh.print_cr("ERROR: ObjectMonitor::exit(): thread=" INTPTR_FORMAT
+ " is exiting an ObjectMonitor it does not own.", p2i(THREAD));
+ lsh.print_cr("The imbalance is possibly caused by JNI locking.");
+ print_debug_style_on(&lsh);
+#endif
+ assert(false, "Non-balanced monitor enter/exit!");
return;
}
}
@@ -908,8 +916,6 @@
// release semantics: prior loads and stores from within the critical section
// must not float (reorder) past the following store that drops the lock.
- // On SPARC that requires MEMBAR #loadstore|#storestore.
- // But of course in TSO #loadstore|#storestore is not required.
OrderAccess::release_store(&_owner, (void*)NULL); // drop the lock
OrderAccess::storeload(); // See if we need to wake a successor
if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
@@ -1106,7 +1112,7 @@
// The _owner field is not always the Thread addr even with an
// inflated monitor, e.g. the monitor can be inflated by a non-owning
// thread due to contention.
-intptr_t ObjectMonitor::complete_exit(TRAPS) {
+intx ObjectMonitor::complete_exit(TRAPS) {
Thread * const Self = THREAD;
assert(Self->is_Java_thread(), "Must be Java thread!");
JavaThread *jt = (JavaThread *)THREAD;
@@ -1122,7 +1128,7 @@
}
guarantee(Self == _owner, "complete_exit not owner");
- intptr_t save = _recursions; // record the old recursion count
+ intx save = _recursions; // record the old recursion count
_recursions = 0; // set the recursion level to be 0
exit(true, Self); // exit the monitor
guarantee(_owner != Self, "invariant");
@@ -1131,7 +1137,7 @@
// reenter() enters a lock and sets recursion count
// complete_exit/reenter operate as a wait without waiting
-void ObjectMonitor::reenter(intptr_t recursions, TRAPS) {
+void ObjectMonitor::reenter(intx recursions, TRAPS) {
Thread * const Self = THREAD;
assert(Self->is_Java_thread(), "Must be Java thread!");
JavaThread *jt = (JavaThread *)THREAD;
@@ -1252,7 +1258,7 @@
_Responsible = NULL;
- intptr_t save = _recursions; // record the old recursion count
+ intx save = _recursions; // record the old recursion count
_waiters++; // increment the number of waiters
_recursions = 0; // set the recursion level to be 1
exit(true, Self); // exit the monitor
@@ -1941,8 +1947,62 @@
void ObjectMonitor::print_on(outputStream* st) const {
// The minimal things to print for markWord printing, more can be added for debugging and logging.
st->print("{contentions=0x%08x,waiters=0x%08x"
- ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
+ ",recursions=" INTX_FORMAT ",owner=" INTPTR_FORMAT "}",
contentions(), waiters(), recursions(),
p2i(owner()));
}
void ObjectMonitor::print() const { print_on(tty); }
+
+#ifdef ASSERT
+// Print the ObjectMonitor like a debugger would:
+//
+// (ObjectMonitor) 0x00007fdfb6012e40 = {
+// _header = 0x0000000000000001
+// _object = 0x000000070ff45fd0
+// _next_om = 0x0000000000000000
+// _pad_buf0 = {
+// [0] = '\0'
+// ...
+// [103] = '\0'
+// }
+// _owner = 0x0000000000000000
+// _previous_owner_tid = 0
+// _recursions = 0
+// _EntryList = 0x0000000000000000
+// _cxq = 0x0000000000000000
+// _succ = 0x0000000000000000
+// _Responsible = 0x0000000000000000
+// _Spinner = 0
+// _SpinDuration = 5000
+// _contentions = 0
+// _WaitSet = 0x0000700009756248
+// _waiters = 1
+// _WaitSetLock = 0
+// }
+//
+void ObjectMonitor::print_debug_style_on(outputStream* st) const {
+ st->print_cr("(ObjectMonitor*) " INTPTR_FORMAT " = {", p2i(this));
+ st->print_cr(" _header = " INTPTR_FORMAT, header().value());
+ st->print_cr(" _object = " INTPTR_FORMAT, p2i(_object));
+ st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(_next_om));
+ st->print_cr(" _pad_buf0 = {");
+ st->print_cr(" [0] = '\\0'");
+ st->print_cr(" ...");
+ st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf0) - 1);
+ st->print_cr(" }");
+ st->print_cr(" _owner = " INTPTR_FORMAT, p2i(_owner));
+ st->print_cr(" _previous_owner_tid = " JLONG_FORMAT, _previous_owner_tid);
+ st->print_cr(" _recursions = " INTX_FORMAT, _recursions);
+ st->print_cr(" _EntryList = " INTPTR_FORMAT, p2i(_EntryList));
+ st->print_cr(" _cxq = " INTPTR_FORMAT, p2i(_cxq));
+ st->print_cr(" _succ = " INTPTR_FORMAT, p2i(_succ));
+ st->print_cr(" _Responsible = " INTPTR_FORMAT, p2i(_Responsible));
+ st->print_cr(" _Spinner = %d", _Spinner);
+ st->print_cr(" _SpinDuration = %d", _SpinDuration);
+ st->print_cr(" _contentions = %d", _contentions);
+ st->print_cr(" _WaitSet = " INTPTR_FORMAT, p2i(_WaitSet));
+ st->print_cr(" _waiters = %d", _waiters);
+ st->print_cr(" _WaitSetLock = %d", _WaitSetLock);
+ st->print_cr("}");
+}
+#endif
--- a/src/hotspot/share/runtime/objectMonitor.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -144,7 +144,7 @@
sizeof(ObjectMonitor *));
void* volatile _owner; // pointer to owning thread OR BasicLock
volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
- volatile intptr_t _recursions; // recursion count, 0 for first entry
+ volatile intx _recursions; // recursion count, 0 for first entry
ObjectWaiter* volatile _EntryList; // Threads blocked on entry or reentry.
// The list is actually composed of WaitNodes,
// acting as proxies for Threads.
@@ -237,7 +237,7 @@
jint waiters() const;
jint contentions() const;
- intptr_t recursions() const { return _recursions; }
+ intx recursions() const { return _recursions; }
// JVM/TI GetObjectMonitorUsage() needs this:
ObjectWaiter* first_waiter() { return _WaitSet; }
@@ -263,7 +263,7 @@
// _recursions == 0 _WaitSet == NULL
DEBUG_ONLY(stringStream ss;)
assert((is_busy() | _recursions) == 0, "freeing in-use monitor: %s, "
- "recursions=" INTPTR_FORMAT, is_busy_to_string(&ss), _recursions);
+ "recursions=" INTX_FORMAT, is_busy_to_string(&ss), _recursions);
_succ = NULL;
_EntryList = NULL;
_cxq = NULL;
@@ -289,11 +289,14 @@
void notifyAll(TRAPS);
void print() const;
+#ifdef ASSERT
+ void print_debug_style_on(outputStream* st) const;
+#endif
void print_on(outputStream* st) const;
// Use the following at your own risk
- intptr_t complete_exit(TRAPS);
- void reenter(intptr_t recursions, TRAPS);
+ intx complete_exit(TRAPS);
+ void reenter(intx recursions, TRAPS);
private:
void AddWaiter(ObjectWaiter* waiter);
--- a/src/hotspot/share/runtime/objectMonitor.inline.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.inline.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -59,7 +59,7 @@
assert(Atomic::load(&_header).value() != 0, "must be non-zero");
assert(_contentions == 0, "must be 0: contentions=%d", _contentions);
assert(_waiters == 0, "must be 0: waiters=%d", _waiters);
- assert(_recursions == 0, "must be 0: recursions=" INTPTR_FORMAT, _recursions);
+ assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions);
assert(_object != NULL, "must be non-NULL");
assert(_owner == NULL, "must be NULL: owner=" INTPTR_FORMAT, p2i(_owner));
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -2626,6 +2626,7 @@
MacroAssembler _masm(&buffer);
SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
assert(*(int*)trampoline != 0, "Instruction(s) for trampoline must not be encoded as zeros.");
+ _masm.flush();
if (PrintInterpreter) {
Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
--- a/src/hotspot/share/runtime/synchronizer.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/synchronizer.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -359,7 +359,7 @@
// 4) reenter lock1 with original recursion count
// 5) lock lock2
// NOTE: must use heavy weight monitor to handle complete_exit/reenter()
-intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
+intx ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
if (UseBiasedLocking) {
BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
@@ -371,7 +371,7 @@
}
// NOTE: must use heavy weight monitor to handle complete_exit/reenter()
-void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
+void ObjectSynchronizer::reenter(Handle obj, intx recursions, TRAPS) {
if (UseBiasedLocking) {
BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
@@ -379,7 +379,7 @@
ObjectMonitor* monitor = inflate(THREAD, obj(), inflate_cause_vm_internal);
- monitor->reenter(recursion, THREAD);
+ monitor->reenter(recursions, THREAD);
}
// -----------------------------------------------------------------------------
// JNI locks on java objects
@@ -1140,7 +1140,7 @@
guarantee(m->object() == NULL, "invariant");
stringStream ss;
guarantee((m->is_busy() | m->_recursions) == 0, "freeing in-use monitor: "
- "%s, recursions=" INTPTR_FORMAT, m->is_busy_to_string(&ss),
+ "%s, recursions=" INTX_FORMAT, m->is_busy_to_string(&ss),
m->_recursions);
// _next_om is used for both per-thread in-use and free lists so
// we have to remove 'm' from the in-use list first (as needed).
--- a/src/hotspot/share/runtime/synchronizer.hpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/synchronizer.hpp Thu Nov 21 13:50:11 2019 +0530
@@ -92,8 +92,8 @@
// used by classloading to free classloader object lock,
// wait on an internal lock, and reclaim original lock
// with original recursion count
- static intptr_t complete_exit(Handle obj, TRAPS);
- static void reenter (Handle obj, intptr_t recursion, TRAPS);
+ static intx complete_exit(Handle obj, TRAPS);
+ static void reenter (Handle obj, intx recursions, TRAPS);
// thread-specific and global ObjectMonitor free list accessors
static ObjectMonitor* om_alloc(Thread* self);
@@ -209,8 +209,8 @@
void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); }
// complete_exit gives up lock completely, returning recursion count
// reenter reclaims lock with original recursion count
- intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
- void reenter(intptr_t recursion, TRAPS) { ObjectSynchronizer::reenter(_obj, recursion, CHECK); }
+ intx complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
+ void reenter(intx recursions, TRAPS) { ObjectSynchronizer::reenter(_obj, recursions, CHECK); }
};
#endif // SHARE_RUNTIME_SYNCHRONIZER_HPP
--- a/src/hotspot/share/runtime/threadSMR.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/threadSMR.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -601,8 +601,6 @@
}
void ThreadsList::dec_nested_handle_cnt() {
- // The decrement only needs to be MO_ACQ_REL since the reference
- // counter is volatile (and the hazard ptr is already NULL).
Atomic::dec(&_nested_handle_cnt);
}
@@ -646,8 +644,6 @@
}
void ThreadsList::inc_nested_handle_cnt() {
- // The increment needs to be MO_SEQ_CST so that the reference counter
- // update is seen before the subsequent hazard ptr update.
Atomic::inc(&_nested_handle_cnt);
}
--- a/src/hotspot/share/runtime/vmStructs.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/runtime/vmStructs.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -911,7 +911,7 @@
unchecked_nonstatic_field(ObjectMonitor, _owner, sizeof(void *)) /* NOTE: no type */ \
volatile_nonstatic_field(ObjectMonitor, _contentions, jint) \
volatile_nonstatic_field(ObjectMonitor, _waiters, jint) \
- volatile_nonstatic_field(ObjectMonitor, _recursions, intptr_t) \
+ volatile_nonstatic_field(ObjectMonitor, _recursions, intx) \
nonstatic_field(ObjectMonitor, _next_om, ObjectMonitor*) \
volatile_nonstatic_field(BasicLock, _displaced_header, markWord) \
nonstatic_field(BasicObjectLock, _lock, BasicLock) \
--- a/src/hotspot/share/services/heapDumper.cpp Wed Nov 20 12:18:46 2019 +0530
+++ b/src/hotspot/share/services/heapDumper.cpp Thu Nov 21 13:50:11 2019 +0530
@@ -1882,7 +1882,7 @@
// The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
// of the heap dump.
HeapObjectDumper obj_dumper(this, writer());
- Universe::heap()->safe_object_iterate(&obj_dumper);
+ Universe::heap()->object_iterate(&obj_dumper);
// HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
do_threads();
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Nov 21 13:50:11 2019 +0530
@@ -156,6 +156,13 @@
int newEvents = ski.translateInterestOps();
int registeredEvents = ski.registeredEvents();
+
+ // DatagramChannelImpl::disconnect has reset socket
+ if (ski.getAndClearReset() && registeredEvents != 0) {
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
+ registeredEvents = 0;
+ }
+
if (newEvents != registeredEvents) {
// add or delete interest in read events
--- a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java Thu Nov 21 13:50:11 2019 +0530
@@ -48,6 +48,7 @@
import sun.security.x509.AlgorithmId;
import sun.security.util.ObjectIdentifier;
+import sun.security.util.SecurityProperties;
/**
* This class implements a protection mechanism for private keys. In JCE, we
@@ -75,14 +76,39 @@
private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
private static final int MAX_ITERATION_COUNT = 5000000;
- private static final int ITERATION_COUNT = 200000;
+ private static final int MIN_ITERATION_COUNT = 10000;
+ private static final int DEFAULT_ITERATION_COUNT = 200000;
private static final int SALT_LEN = 20; // the salt length
private static final int DIGEST_LEN = 20;
+ private static final int ITERATION_COUNT;
// the password used for protecting/recovering keys passed through this
// key protector
private char[] password;
+ /**
+ * {@systemProperty jdk.jceks.iterationCount} property indicating the
+ * number of iterations for password-based encryption (PBE) in JCEKS
+ * keystores. Values in the range 10000 to 5000000 are considered valid.
+ * If the value is out of this range, or is not a number, or is
+ * unspecified; a default of 200000 is used.
+ */
+ static {
+ int iterationCount = DEFAULT_ITERATION_COUNT;
+ String ic = SecurityProperties.privilegedGetOverridable(
+ "jdk.jceks.iterationCount");
+ if (ic != null && !ic.isEmpty()) {
+ try {
+ iterationCount = Integer.parseInt(ic);
+ if (iterationCount < MIN_ITERATION_COUNT ||
+ iterationCount > MAX_ITERATION_COUNT) {
+ iterationCount = DEFAULT_ITERATION_COUNT;
+ }
+ } catch (NumberFormatException e) {}
+ }
+ ITERATION_COUNT = iterationCount;
+ }
+
KeyProtector(char[] password) {
if (password == null) {
throw new IllegalArgumentException("password can't be null");
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,8 @@
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
+import java.util.Arrays;
+import java.util.function.Consumer;
/**
@@ -172,6 +174,20 @@
}
/**
+ * Invokes an action for each key.
+ *
+ * This method is invoked by DatagramChannelImpl::disconnect.
+ */
+ private void forEach(Consumer<SelectionKey> action) {
+ synchronized (keyLock) {
+ SelectionKey[] keys = this.keys;
+ if (keys != null) {
+ Arrays.stream(keys).filter(k -> k != null).forEach(action::accept);
+ }
+ }
+ }
+
+ /**
* Registers this channel with the given selector, returning a selection key.
*
* <p> This method first verifies that this channel is open and that the
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Nov 21 13:50:11 2019 +0530
@@ -31,6 +31,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.ref.Cleaner.Cleanable;
+import java.lang.reflect.Method;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.Inet6Address;
@@ -54,12 +55,18 @@
import java.nio.channels.MembershipKey;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
+import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
import jdk.internal.ref.CleanerFactory;
import sun.net.ResourceManager;
@@ -113,10 +120,13 @@
private long readerThread;
private long writerThread;
- // Binding and remote address (when connected)
+ // Local and remote (connected) address
private InetSocketAddress localAddress;
private InetSocketAddress remoteAddress;
+ // Local address prior to connecting
+ private InetSocketAddress initialLocalAddress;
+
// Socket adaptor, created lazily
private static final VarHandle SOCKET;
static {
@@ -1103,6 +1113,9 @@
bindInternal(null);
}
+ // capture local address before connect
+ initialLocalAddress = localAddress;
+
int n = Net.connect(family,
fd,
isa.getAddress(),
@@ -1160,21 +1173,19 @@
remoteAddress = null;
state = ST_UNCONNECTED;
- // check whether rebind is needed
- InetSocketAddress isa = Net.localAddress(fd);
- if (isa.getPort() == 0) {
- // On Linux, if bound to ephemeral port,
- // disconnect does not preserve that port.
- // In this case, try to rebind to the previous port.
- int port = localAddress.getPort();
- localAddress = isa; // in case Net.bind fails
- Net.bind(family, fd, isa.getAddress(), port);
- isa = Net.localAddress(fd); // refresh address
- assert isa.getPort() == port;
+ // refresh localAddress, should be same as it was prior to connect
+ localAddress = Net.localAddress(fd);
+ try {
+ if (!localAddress.equals(initialLocalAddress)) {
+ // Workaround connect(2) issues on Linux and macOS
+ repairSocket(initialLocalAddress);
+ assert (localAddress != null)
+ && localAddress.equals(Net.localAddress(fd))
+ && localAddress.equals(initialLocalAddress);
+ }
+ } finally {
+ initialLocalAddress = null;
}
-
- // refresh localAddress
- localAddress = isa;
}
} finally {
writeLock.unlock();
@@ -1186,6 +1197,134 @@
}
/**
+ * "Repair" the channel's socket after a disconnect that didn't restore the
+ * local address.
+ *
+ * On Linux, connect(2) dissolves the association but changes the local port
+ * to 0 when it was initially bound to an ephemeral port. The workaround here
+ * is to rebind to the original port.
+ *
+ * On macOS, connect(2) dissolves the association but rebinds the socket to
+ * the wildcard address when it was initially bound to a specific address.
+ * The workaround here is to re-create the socket.
+ */
+ private void repairSocket(InetSocketAddress target)
+ throws IOException
+ {
+ assert Thread.holdsLock(stateLock);
+
+ // Linux: try to bind the socket to the original address/port
+ if (localAddress.getPort() == 0) {
+ assert localAddress.getAddress().equals(target.getAddress());
+ Net.bind(family, fd, target.getAddress(), target.getPort());
+ localAddress = Net.localAddress(fd);
+ return;
+ }
+
+ // capture the value of all existing socket options
+ Map<SocketOption<?>, Object> map = new HashMap<>();
+ for (SocketOption<?> option : supportedOptions()) {
+ Object value = getOption(option);
+ if (value != null) {
+ map.put(option, value);
+ }
+ }
+
+ // macOS: re-create the socket.
+ FileDescriptor newfd = Net.socket(family, false);
+ try {
+ // copy the socket options that are protocol family agnostic
+ for (Map.Entry<SocketOption<?>, Object> e : map.entrySet()) {
+ SocketOption<?> option = e.getKey();
+ if (SocketOptionRegistry.findOption(option, Net.UNSPEC) != null) {
+ Object value = e.getValue();
+ try {
+ Net.setSocketOption(newfd, Net.UNSPEC, option, value);
+ } catch (IOException ignore) { }
+ }
+ }
+
+ // copy the blocking mode
+ if (!isBlocking()) {
+ IOUtil.configureBlocking(newfd, false);
+ }
+
+ // dup this channel's socket to the new socket. If this succeeds then
+ // fd will reference the new socket. If it fails then it will still
+ // reference the old socket.
+ nd.dup(newfd, fd);
+ } finally {
+ // release the file descriptor
+ nd.close(newfd);
+ }
+
+ // bind to the original local address
+ try {
+ Net.bind(family, fd, target.getAddress(), target.getPort());
+ } catch (IOException ioe) {
+ // bind failed, socket is left unbound
+ localAddress = null;
+ throw ioe;
+ }
+
+ // restore local address
+ localAddress = Net.localAddress(fd);
+
+ // restore all socket options (including those set in first pass)
+ for (Map.Entry<SocketOption<?>, Object> e : map.entrySet()) {
+ @SuppressWarnings("unchecked")
+ SocketOption<Object> option = (SocketOption<Object>) e.getKey();
+ Object value = e.getValue();
+ try {
+ setOption(option, value);
+ } catch (IOException ignore) { }
+ }
+
+ // restore multicast group membership
+ MembershipRegistry registry = this.registry;
+ if (registry != null) {
+ registry.forEach(k -> {
+ if (k instanceof MembershipKeyImpl.Type6) {
+ MembershipKeyImpl.Type6 key6 = (MembershipKeyImpl.Type6) k;
+ Net.join6(fd, key6.groupAddress(), key6.index(), key6.source());
+ } else {
+ MembershipKeyImpl.Type4 key4 = (MembershipKeyImpl.Type4) k;
+ Net.join4(fd, key4.groupAddress(), key4.interfaceAddress(), key4.source());
+ }
+ });
+ }
+
+ // reset registration in all Selectors that this channel is registered with
+ AbstractSelectableChannels.forEach(this, SelectionKeyImpl::reset);
+ }
+
+ /**
+ * Defines static methods to access AbstractSelectableChannel non-public members.
+ */
+ private static class AbstractSelectableChannels {
+ private static final Method FOREACH;
+ static {
+ try {
+ PrivilegedExceptionAction<Method> pae = () -> {
+ Method m = AbstractSelectableChannel.class.getDeclaredMethod("forEach", Consumer.class);
+ m.setAccessible(true);
+ return m;
+ };
+ FOREACH = AccessController.doPrivileged(pae);
+ } catch (Exception e) {
+ throw new InternalError(e);
+ }
+ }
+ static void forEach(AbstractSelectableChannel ch, Consumer<SelectionKeyImpl> action) {
+ try {
+ FOREACH.invoke(ch, action);
+ } catch (Exception e) {
+ throw new InternalError(e);
+ }
+ }
+ }
+
+ /**
* Joins channel's socket to the given group/interface and
* optional source address.
*/
--- a/src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,14 @@
package sun.nio.ch;
-import java.nio.channels.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
-import java.util.*;
+import java.nio.channels.MembershipKey;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
/**
* Simple registry of membership keys for a MulticastChannel.
@@ -38,8 +42,8 @@
class MembershipRegistry {
- // map multicast group to keys
- private Map<InetAddress,List<MembershipKeyImpl>> groups = null;
+ // map multicast group to list of keys
+ private Map<InetAddress, List<MembershipKeyImpl>> groups;
MembershipRegistry() {
}
@@ -116,16 +120,29 @@
}
}
+ @FunctionalInterface
+ interface ThrowingConsumer<T, X extends Throwable> {
+ void accept(T action) throws X;
+ }
+
+ /**
+ * Invoke an action for each key in the registry
+ */
+ <X extends Throwable>
+ void forEach(ThrowingConsumer<MembershipKeyImpl, X> action) throws X {
+ if (groups != null) {
+ for (List<MembershipKeyImpl> keys : groups.values()) {
+ for (MembershipKeyImpl key : keys) {
+ action.accept(key);
+ }
+ }
+ }
+ }
+
/**
* Invalidate all keys in the registry
*/
void invalidateAll() {
- if (groups != null) {
- for (InetAddress group: groups.keySet()) {
- for (MembershipKeyImpl key: groups.get(group)) {
- key.invalidate();
- }
- }
- }
+ forEach(MembershipKeyImpl::invalidate);
}
}
--- a/src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java Thu Nov 21 13:50:11 2019 +0530
@@ -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
@@ -25,15 +25,15 @@
package sun.nio.ch;
-import java.io.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
/**
* Allows different platforms to call different native methods
* for read and write operations.
*/
-abstract class NativeDispatcher
-{
+abstract class NativeDispatcher {
abstract int read(FileDescriptor fd, long address, int len)
throws IOException;
@@ -77,4 +77,13 @@
// Do nothing by default; this is only needed on Unix
}
+ /**
+ * Duplicates a file descriptor.
+ * @param fd1 the file descriptor to duplicate
+ * @param fd2 the new file descriptor, the socket or file that it is connected
+ * to will be closed by this method
+ */
+ void dup(FileDescriptor fd1, FileDescriptor fd2) throws IOException {
+ throw new UnsupportedOperationException();
+ }
}
--- a/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,9 @@
// registered events in kernel, used by some Selector implementations
private int registeredEvents;
+ // registered events need to be reset, used by some Selector implementations
+ private volatile boolean reset;
+
// index of key in pollfd array, used by some Selector implementations
private int index;
@@ -184,6 +187,26 @@
index = i;
}
+ /**
+ * Sets the reset flag, re-queues the key, and wakeups up the Selector
+ */
+ void reset() {
+ reset = true;
+ selector.setEventOps(this);
+ selector.wakeup();
+ }
+
+ /**
+ * Clears the reset flag, returning the previous value of the flag
+ */
+ boolean getAndClearReset() {
+ assert Thread.holdsLock(selector);
+ boolean r = reset;
+ if (r)
+ reset = false;
+ return r;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
--- a/src/java.base/share/conf/security/java.security Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/share/conf/security/java.security Thu Nov 21 13:50:11 2019 +0530
@@ -1066,6 +1066,16 @@
jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep;\
java.base/java.security.KeyRep$Type;java.base/javax.crypto.spec.SecretKeySpec;!*
+# The iteration count used for password-based encryption (PBE) in JCEKS
+# keystores. Values in the range 10000 to 5000000 are considered valid.
+# If the value is out of this range, or is not a number, or is unspecified;
+# a default of 200000 is used.
+#
+# If the system property jdk.jceks.iterationCount is also specified, it
+# supersedes the security property value defined here.
+#
+#jdk.jceks.iterationCount = 200000
+
#
# PKCS12 KeyStore properties
#
--- a/src/java.base/unix/classes/sun/nio/ch/DatagramDispatcher.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/unix/classes/sun/nio/ch/DatagramDispatcher.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, 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
@@ -25,16 +25,16 @@
package sun.nio.ch;
-import java.io.*;
-import java.net.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
/**
* Allows different platforms to call different native methods
* for read and write operations.
*/
-class DatagramDispatcher extends NativeDispatcher
-{
+class DatagramDispatcher extends NativeDispatcher {
+
static {
IOUtil.load();
}
@@ -63,6 +63,10 @@
FileDispatcherImpl.preClose0(fd);
}
+ void dup(FileDescriptor fd1, FileDescriptor fd2) throws IOException {
+ FileDispatcherImpl.dup0(fd1, fd2);
+ }
+
static native int read0(FileDescriptor fd, long address, int len)
throws IOException;
--- a/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -108,6 +108,10 @@
preClose0(fd);
}
+ void dup(FileDescriptor fd1, FileDescriptor fd2) throws IOException {
+ dup0(fd1, fd2);
+ }
+
FileDescriptor duplicateForMapping(FileDescriptor fd) {
// file descriptor not required for mapping operations; okay
// to return invalid file descriptor.
@@ -176,6 +180,8 @@
static native void preClose0(FileDescriptor fd) throws IOException;
+ static native void dup0(FileDescriptor fd1, FileDescriptor fd2) throws IOException;
+
static native void closeIntFD(int fd) throws IOException;
static native int setDirect0(FileDescriptor fd) throws IOException;
--- a/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c Thu Nov 21 13:50:11 2019 +0530
@@ -312,6 +312,14 @@
}
JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_dup0(JNIEnv *env, jobject this, jobject fdo1, jobject fdo2)
+{
+ if (dup2(fdval(env, fdo1), fdval(env, fdo2)) < 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
+ }
+}
+
+JNIEXPORT void JNICALL
Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd)
{
closeFileDescriptor(env, fd);
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/ImageSurfaceData.m Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/ImageSurfaceData.m Thu Nov 21 13:50:11 2019 +0530
@@ -1768,6 +1768,10 @@
PRINT("Java_sun_java2d_OSXOffScreenSurfaceData_initRaster")
ImageSDOps* isdo = (ImageSDOps*)SurfaceData_InitOps(env, bisd, sizeof(ImageSDOps));
+ if (isdo == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+ return;
+ }
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterSurfaceData.m Wed Nov 20 12:18:46 2019 +0530
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterSurfaceData.m Thu Nov 21 13:50:11 2019 +0530
@@ -25,6 +25,7 @@
#import "PrinterSurfaceData.h"
+#import "jni_util.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
@@ -87,6 +88,11 @@
PRINT("Java_sun_lwawt_macosx_CPrinterSurfaceData_initOps")
PrintSDOps *psdo = (PrintSDOps*)SurfaceData_InitOps(env, jthis, sizeof(PrintSDOps));
+ if (psdo == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+ return;
+ }
+
psdo->nsRef = (NSGraphicsContext*)jlong_to_ptr(nsRef);
psdo->width = width;
psdo->height = height;
--- a/test/hotspot/jtreg/compiler/compilercontrol/CompilationModeHighOnlyTest.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/hotspot/jtreg/compiler/compilercontrol/CompilationModeHighOnlyTest.java Thu Nov 21 13:50:11 2019 +0530
@@ -26,6 +26,7 @@
* @bug 8233885
* @summary CompLevel_initial_compile should be CompLevel_full_optimization for high-only mode
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompilationMode=high-only
+ * -XX:CompileCommand=compileonly,java.lang.Object::<init>
* compiler.compilercontrol.CompilationModeHighOnlyTest
*
*/
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Thu Nov 21 13:50:11 2019 +0530
@@ -35,12 +35,14 @@
* java.management
* @build sun.hotspot.WhiteBox
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
- * @run main gc.g1.TestGCLogMessages
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * gc.g1.TestGCLogMessages
*/
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
-import jdk.test.lib.Platform;
+import sun.hotspot.code.Compiler;
public class TestGCLogMessages {
@@ -85,7 +87,7 @@
}
public boolean isAvailable() {
- return Platform.isGraal() || Platform.isServer();
+ return Compiler.isC2Enabled() || Compiler.isGraalEnabled();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/z/TestSmallHeap.java Thu Nov 21 13:50:11 2019 +0530
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package gc.z;
+
+/*
+ * @test TestSmallHeap
+ * @requires vm.gc.Z & !vm.graal.enabled
+ * @summary Test ZGC with small heaps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx8M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx16M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx32M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx64M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx128M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx256M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx512M gc.z.TestSmallHeap
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc,gc+init,gc+heap -Xmx1024M gc.z.TestSmallHeap
+ */
+
+import java.lang.ref.Reference;
+
+public class TestSmallHeap {
+ public static void main(String[] args) throws Exception {
+ final long maxCapacity = Runtime.getRuntime().maxMemory();
+ System.out.println("Max Capacity " + maxCapacity + " bytes");
+
+ // Allocate byte arrays of increasing length, so that
+ // all allocaion paths (small/medium/large) are tested.
+ for (int length = 16; length <= maxCapacity / 16; length *= 2) {
+ System.out.println("Allocating " + length + " bytes");
+ Reference.reachabilityFence(new byte[length]);
+ }
+
+ System.out.println("Success");
+ }
+}
--- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java Thu Nov 21 13:50:11 2019 +0530
@@ -67,8 +67,6 @@
VMType = "-client";
} else if (Platform.isMinimal()) {
VMType = "-minimal";
- } else if (Platform.isGraal()) {
- VMType = "-graal";
} else {
VMType = null;
}
--- a/test/hotspot/jtreg/runtime/Safepoint/NoSafepointVerifier.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/hotspot/jtreg/runtime/Safepoint/NoSafepointVerifier.java Thu Nov 21 13:50:11 2019 +0530
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8184732
- * @summary Ensure that special locks never safepoint check and are vm_block.
+ * @summary Ensure that special locks never safepoint check.
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@@ -57,22 +57,18 @@
}
static String test1 = "Special locks or below should never safepoint";
- static String test2 = "Special locks or below should allow the vm to block";
- static String test3 = "Possible safepoint reached by thread that does not allow it";
+ static String test2 = "Possible safepoint reached by thread that does not allow it";
public static void main(String args[]) throws Exception {
if (args.length > 0) {
if (args[0].equals(test1)) {
WhiteBox.getWhiteBox().assertSpecialLock(/*vm_block*/true, /*safepoint_check_always*/true);
} else if (args[0].equals(test2)) {
- WhiteBox.getWhiteBox().assertSpecialLock(/*vm_block*/false, /*safepoint_check_always*/false);
- } else if (args[0].equals(test3)) {
WhiteBox.getWhiteBox().assertSpecialLock(/*vm_block*/true, /*safepoint_check_always*/false);
}
} else {
runTest(test1);
runTest(test2);
- runTest(test3);
}
}
}
--- a/test/hotspot/jtreg/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/hotspot/jtreg/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,7 @@
ARCH("isAArch64", "isARM", "isPPC", "isS390x", "isSparc", "isX64", "isX86"),
BITNESS("is32bit", "is64bit"),
OS("isAix", "isLinux", "isOSX", "isSolaris", "isWindows"),
- VM_TYPE("isClient", "isServer", "isGraal", "isMinimal", "isZero", "isEmbedded"),
+ VM_TYPE("isClient", "isServer", "isMinimal", "isZero", "isEmbedded"),
MODE("isInt", "isMixed", "isComp"),
IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild",
"isSlowDebugBuild", "hasSA", "shouldSAAttach", "isTieredSupported",
--- a/test/jdk/ProblemList.txt Wed Nov 20 12:18:46 2019 +0530
+++ b/test/jdk/ProblemList.txt Thu Nov 21 13:50:11 2019 +0530
@@ -894,7 +894,7 @@
com/sun/jdi/RepStep.java 8043571 generic-all
-com/sun/jdi/NashornPopFrameTest.java 8187143 generic-all
+com/sun/jdi/NashornPopFrameTest.java 8225620 generic-all
############################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/crypto/provider/KeyProtector/IterationCount.java Thu Nov 21 13:50:11 2019 +0530
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8233404
+ * @library /test/lib
+ * @run main/othervm/timeout=30 IterationCount HOST 200000
+ * @run main/othervm/timeout=30 IterationCount HOST 200000 1
+ * @run main/othervm/timeout=30 IterationCount HOST 200000 6000000
+ * @run main/othervm/timeout=30 IterationCount HOST 200000 invalid
+ * @run main/othervm/timeout=30 IterationCount HOST 30000 30000
+ * @run main/othervm/timeout=30 IterationCount OVERRIDE
+ * @author Martin Balao (mbalao@redhat.com)
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class IterationCount {
+ private static final String clientStr = "CLIENT";
+ private static final String javaBinPath =
+ System.getProperty("java.home", ".") + File.separator + "bin" +
+ File.separator + "java";
+
+ public static void main(String[] args) throws Throwable {
+ if (args[0].equals("HOST")) {
+ String setValue = null;
+ if (args.length > 2) {
+ setValue = args[2];
+ }
+ testSystem(args[1], setValue);
+ testSecurity(args[1], setValue);
+ } else if (args[0].equals(clientStr)) {
+ int expectedIterationCount = Integer.parseInt(args[1]);
+ int currentIterationCount = getCurrentIterationCountValue();
+ System.out.println("Expected value: " + expectedIterationCount);
+ System.out.println("Current value: " + currentIterationCount);
+ if (currentIterationCount != expectedIterationCount) {
+ throw new Exception("Expected value different than current");
+ }
+ } else if (args[0].equals("OVERRIDE")) {
+ testSystemOverridesSecurity();
+ }
+ System.out.println("TEST PASS - OK");
+ }
+
+ private static List<String> getBasicCommand() {
+ List<String> cmd = new ArrayList<>();
+ cmd.add(javaBinPath);
+ cmd.add("-cp");
+ cmd.add(System.getProperty("test.classes", "."));
+ return cmd;
+ }
+
+ private static void executeCommand(List<String> cmd, String expectedCount)
+ throws Throwable {
+ cmd.add(IterationCount.class.getName());
+ cmd.add(clientStr);
+ cmd.add(expectedCount);
+ OutputAnalyzer out = ProcessTools.executeCommand(
+ cmd.toArray(new String[cmd.size()]));
+ out.shouldHaveExitValue(0);
+ }
+
+ private static void testSystem(String expectedCount, String setValue)
+ throws Throwable {
+ System.out.println("Test setting " +
+ (setValue != null ? setValue : "nothing") +
+ " as a System property");
+ List<String> cmd = getBasicCommand();
+ if (setValue != null) {
+ cmd.add("-Djdk.jceks.iterationCount=" + setValue);
+ }
+ executeCommand(cmd, expectedCount);
+ System.out.println(".............................");
+ }
+
+ private static void testSecurity(String expectedCount, String setValue)
+ throws Throwable {
+ testSecurity(expectedCount, setValue, getBasicCommand());
+ }
+
+ private static void testSecurity(String expectedCount, String setValue,
+ List<String> cmd) throws Throwable {
+ System.out.println("Test setting " +
+ (setValue != null ? setValue : "nothing") +
+ " as a Security property");
+ Path tmpDirPath = Files.createTempDirectory("tmpdir");
+ try {
+ if (setValue != null) {
+ String javaSecurityPath = tmpDirPath +
+ File.separator + "java.security";
+ writeJavaSecurityProp(javaSecurityPath, setValue);
+ cmd.add("-Djava.security.properties=" + javaSecurityPath);
+ }
+ executeCommand(cmd, expectedCount);
+ System.out.println(".............................");
+ } finally {
+ deleteDir(tmpDirPath);
+ }
+ }
+
+ private static void testSystemOverridesSecurity() throws Throwable {
+ System.out.println("Test that setting a System property overrides" +
+ " the Security one");
+ String systemValue = Integer.toString(30000);
+ System.out.println("System value: " + systemValue);
+ List<String> cmd = getBasicCommand();
+ cmd.add("-Djdk.jceks.iterationCount=" + systemValue);
+ testSecurity(systemValue, Integer.toString(40000), cmd);
+ }
+
+ private static void writeJavaSecurityProp(String javaSecurityPath,
+ String setValue) throws IOException {
+ try (FileOutputStream fos = new FileOutputStream(
+ new File(javaSecurityPath))) {
+ fos.write(("jdk.jceks.iterationCount=" + setValue).getBytes());
+ }
+ }
+
+ private static int getCurrentIterationCountValue() throws Exception {
+ Class<?> KeyProtectorClass =
+ Class.forName("com.sun.crypto.provider.KeyProtector");
+ Field iterationCountField =
+ KeyProtectorClass.getDeclaredField("ITERATION_COUNT");
+ iterationCountField.setAccessible(true);
+ return iterationCountField.getInt(KeyProtectorClass);
+ }
+
+ private static void deleteDir(Path directory) throws IOException {
+ Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
+
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs) throws IOException {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+}
--- a/test/jdk/java/nio/channels/DatagramChannel/AddressesAfterDisconnect.java Wed Nov 20 12:18:46 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @library /test/lib
- * @summary Test DatagramChannel local address after disconnect.
- * @requires (os.family != "mac")
- * @run testng/othervm AddressesAfterDisconnect
- * @run testng/othervm -Djava.net.preferIPv6Addresses=true AddressesAfterDisconnect
- * @run testng/othervm -Djava.net.preferIPv4Stack=true AddressesAfterDisconnect
- */
-
-import jdk.test.lib.net.IPSupport;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.net.StandardProtocolFamily;
-import java.nio.channels.DatagramChannel;
-
-import org.testng.annotations.Test;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertFalse;
-
-public class AddressesAfterDisconnect {
-
- public static void main(String[] args) throws IOException {
- new AddressesAfterDisconnect().execute();
- }
-
- @Test
- public void execute() throws IOException {
- IPSupport.throwSkippedExceptionIfNonOperational();
- boolean preferIPv6 = Boolean.getBoolean("java.net.preferIPv6Addresses");
-
- // test with default protocol family
- try (DatagramChannel dc = DatagramChannel.open()) {
- System.out.println("Test with default");
- dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
- test(dc);
- test(dc);
- }
-
- if (IPSupport.hasIPv6()) {
- // test with IPv6 only
- System.out.println("Test with IPv6 only");
- try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET6)) {
- dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
- test(dc);
- test(dc);
- }
- }
-
- if (IPSupport.hasIPv4() && !preferIPv6) {
- // test with IPv4 only
- System.out.println("Test with IPv4 only");
- try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)) {
- dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
- test(dc);
- test(dc);
- }
- }
- }
-
- /**
- * Connect DatagramChannel to a server, write a datagram and disconnect. Invoke
- * a second or subsequent time with the same DatagramChannel instance to check
- * that disconnect works as expected.
- */
- static void test(DatagramChannel dc) throws IOException {
- SocketAddress local = dc.getLocalAddress();
- try (DatagramChannel server = DatagramChannel.open()) {
- server.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
- SocketAddress remote = server.getLocalAddress();
- dc.connect(remote);
- assertTrue(dc.isConnected());
- // comment the following two lines on OS X to see JDK-8231259
- assertEquals(dc.getLocalAddress(), local, "local address after connect");
- assertEquals(dc.getRemoteAddress(), remote, "remote address after connect");
- dc.disconnect();
- assertFalse(dc.isConnected());
- assertEquals(dc.getLocalAddress(), local, "local address after disconnect");
- assertEquals(dc.getRemoteAddress(), null, "remote address after disconnect");
- }
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/AfterDisconnect.java Thu Nov 21 13:50:11 2019 +0530
@@ -0,0 +1,228 @@
+/*
+ * 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 8231880 8231258
+ * @library /test/lib
+ * @summary Test DatagramChannel bound to specific address/ephemeral port after disconnect
+ * @run testng/othervm AfterDisconnect
+ * @run testng/othervm -Djava.net.preferIPv4Stack=true AfterDisconnect
+ * @run testng/othervm -Djava.net.preferIPv6Addresses=true AfterDisconnect
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketOption;
+import java.net.StandardSocketOptions;
+import java.net.StandardProtocolFamily;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.MembershipKey;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import jdk.test.lib.net.IPSupport;
+
+public class AfterDisconnect {
+
+ @Test
+ public void execute() throws IOException {
+ IPSupport.throwSkippedExceptionIfNonOperational();
+ boolean preferIPv6 = Boolean.getBoolean("java.net.preferIPv6Addresses");
+ InetAddress lb = InetAddress.getLoopbackAddress();
+
+ // test with default protocol family
+ try (DatagramChannel dc = DatagramChannel.open()) {
+ System.out.println("Test with default");
+ dc.bind(new InetSocketAddress(lb, 0));
+ test(dc);
+ test(dc);
+ }
+
+ // test with IPv6 socket
+ if (IPSupport.hasIPv6()) {
+ System.out.println("Test with IPv6 socket");
+ try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET6)) {
+ dc.bind(new InetSocketAddress(lb, 0));
+ test(dc);
+ test(dc);
+ }
+ }
+
+ // test with IPv4 socket
+ if (IPSupport.hasIPv4() && !preferIPv6) {
+ System.out.println("Test with IPv4 socket");
+ try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)) {
+ dc.bind(new InetSocketAddress(lb, 0));
+ test(dc);
+ test(dc);
+ }
+ }
+ }
+
+ void test(DatagramChannel dc) throws IOException {
+ testLocalAddress(dc);
+ testSocketOptions(dc);
+ testSelectorRegistration(dc);
+ testMulticastGroups(dc);
+ }
+
+ /**
+ * Test that disconnect restores local address
+ */
+ void testLocalAddress(DatagramChannel dc) throws IOException {
+ try (DatagramChannel server = DatagramChannel.open()) {
+ server.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+
+ SocketAddress local = dc.getLocalAddress();
+ SocketAddress remote = server.getLocalAddress();
+
+ dc.connect(remote);
+ assertTrue(dc.isConnected());
+ assertEquals(dc.getLocalAddress(), local);
+ assertEquals(dc.getRemoteAddress(), remote);
+
+ dc.disconnect();
+ assertFalse(dc.isConnected());
+ assertEquals(dc.getLocalAddress(), local);
+ assertTrue(dc.getRemoteAddress() == null);
+ }
+ }
+
+ /**
+ * Test that disconnect does not change socket options
+ */
+ void testSocketOptions(DatagramChannel dc) throws IOException {
+ // set a few socket options
+ dc.setOption(StandardSocketOptions.SO_SNDBUF, 32*1024);
+ dc.setOption(StandardSocketOptions.SO_RCVBUF, 64*1024);
+ InetAddress ia = dc.socket().getLocalAddress();
+ NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
+ if (ni != null && ni.supportsMulticast())
+ dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
+
+ // capture values of socket options
+ Map<SocketOption<?>, Object> map = options(dc);
+
+ dc.connect(dc.getLocalAddress());
+ dc.disconnect();
+
+ // check socket options have not changed
+ assertEquals(map, options(dc));
+ }
+
+ /**
+ * Returns a map of the given channel's socket options and values.
+ */
+ private Map<SocketOption<?>, Object> options(DatagramChannel dc) throws IOException {
+ Map<SocketOption<?>, Object> map = new HashMap<>();
+ for (SocketOption<?> option : dc.supportedOptions()) {
+ try {
+ Object value = dc.getOption(option);
+ if (value != null) {
+ map.put(option, value);
+ }
+ } catch (IOException ignore) { }
+ }
+ return map;
+ }
+
+ /**
+ * Test that disconnect does not interfere with Selector registrations
+ */
+ void testSelectorRegistration(DatagramChannel dc) throws IOException {
+ try (Selector sel = Selector.open()) {
+ dc.configureBlocking(false);
+ SelectionKey key = dc.register(sel, SelectionKey.OP_READ);
+
+ // ensure socket is registered
+ sel.selectNow();
+
+ dc.connect(dc.getLocalAddress());
+ dc.disconnect();
+
+ // selection key should still be valid
+ assertTrue(key.isValid());
+
+ // check blocking mode with non-blocking receive
+ ByteBuffer bb = ByteBuffer.allocate(100);
+ SocketAddress sender = dc.receive(bb);
+ assertTrue(sender == null);
+
+ // send datagram and ensure that channel is selected
+ dc.send(ByteBuffer.wrap("Hello".getBytes("UTF-8")), dc.getLocalAddress());
+ assertFalse(key.isReadable());
+ while (sel.select() == 0);
+ assertTrue(key.isReadable());
+ sender = dc.receive(bb);
+ assertEquals(sender, dc.getLocalAddress());
+
+ // cancel key, flush from Selector, and restore blocking mode
+ key.cancel();
+ sel.selectNow();
+ dc.configureBlocking(true);
+ }
+ }
+
+ /**
+ * Test that disconnect does not interfere with multicast group membership
+ */
+ void testMulticastGroups(DatagramChannel dc) throws IOException {
+ InetAddress localAddress = dc.socket().getLocalAddress();
+ InetAddress group;
+ if (localAddress instanceof Inet6Address) {
+ group = InetAddress.getByName("ff02::a");
+ } else {
+ group = InetAddress.getByName("225.4.5.6");
+ }
+ NetworkInterface ni = NetworkInterface.getByInetAddress(localAddress);
+ if (ni != null && ni.supportsMulticast()) {
+ // join group
+ MembershipKey key = dc.join(group, ni);
+
+ dc.connect(dc.getLocalAddress());
+ dc.disconnect();
+
+ // membership key should still be valid
+ assertTrue(key.isValid());
+
+ // send datagram to multicast group, should be received
+ dc.send(ByteBuffer.wrap("Hello".getBytes("UTF-8")), dc.getLocalAddress());
+ ByteBuffer bb = ByteBuffer.allocate(100);
+ SocketAddress sender = dc.receive(bb);
+ assertEquals(sender, dc.getLocalAddress());
+
+ // drop membership
+ key.drop();
+ }
+ }
+}
--- a/test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java Thu Nov 21 13:50:11 2019 +0530
@@ -43,7 +43,7 @@
* @requires vm.hasJFR
* @library /test/lib
*
- * @run main/othervm jdk.jfr.event.runtime.TestBiasedLockRevocationEvents
+ * @run main/othervm -XX:+UseBiasedLocking jdk.jfr.event.runtime.TestBiasedLockRevocationEvents
*/
public class TestBiasedLockRevocationEvents {
--- a/test/langtools/tools/javac/processing/model/testgetallmembers/Main.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/langtools/tools/javac/processing/model/testgetallmembers/Main.java Thu Nov 21 13:50:11 2019 +0530
@@ -27,7 +27,7 @@
* @summary PackageElement.getEnclosedElements() throws ClassReader$BadClassFileException
* @author Peter von der Ah\u00e9
* @modules jdk.compiler/com.sun.tools.javac.model
- * @run main/othervm -Xmx256m Main
+ * @run main/othervm -Xmx512m Main
*/
import java.io.File;
--- a/test/lib/jdk/test/lib/Platform.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/lib/jdk/test/lib/Platform.java Thu Nov 21 13:50:11 2019 +0530
@@ -59,10 +59,6 @@
return vmName.endsWith(" Server VM");
}
- public static boolean isGraal() {
- return vmName.endsWith(" Graal VM");
- }
-
public static boolean isZero() {
return vmName.endsWith(" Zero VM");
}
--- a/test/lib/jdk/test/lib/cli/CommandLineOptionTest.java Wed Nov 20 12:18:46 2019 +0530
+++ b/test/lib/jdk/test/lib/cli/CommandLineOptionTest.java Thu Nov 21 13:50:11 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, 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
@@ -500,8 +500,6 @@
return "-client";
} else if (Platform.isMinimal()) {
return "-minimal";
- } else if (Platform.isGraal()) {
- return "-graal";
}
throw new RuntimeException("Unknown VM mode.");
}