# HG changeset patch # User psadhukhan # Date 1574324411 -19800 # Node ID 7567ce83f3b5006832cb968c12d6a45d88e6cf33 # Parent b9bde9d224b959dc4b2404ee0ca681b0dd6b9573# Parent 51673a0b6df01b21c4ca7fbd4e8820603ea10f45 Merge diff -r b9bde9d224b9 -r 7567ce83f3b5 .hgtags --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 make/data/fontconfig/aix.fontconfig.properties --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/cpu/x86/macroAssembler_x86.cpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/os/bsd/os_bsd.cpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/classfile/systemDictionary.cpp --- 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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/epsilon/epsilonHeap.cpp --- 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 { diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/epsilon/epsilonHeap.hpp --- 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; } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/g1/g1CollectedHeap.hpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/collectedHeap.hpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/genCollectedHeap.cpp --- 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) { diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/genCollectedHeap.hpp --- 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, diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/generation.cpp --- 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) { diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/generation.hpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/space.cpp --- 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), diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/space.hpp --- 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 - 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"); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shared/space.inline.hpp --- 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 -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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- 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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp --- 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(); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zArguments.cpp --- 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) { diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zCollectedHeap.cpp --- 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); } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zCollectedHeap.hpp --- 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 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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zDirector.cpp --- 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; } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zDriver.cpp --- 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(); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zGlobals.cpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zGlobals.hpp --- 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; // diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zHeuristics.cpp --- /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); +} diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zHeuristics.hpp --- /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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zInitialize.cpp --- 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(); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zObjectAllocator.cpp --- 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(); } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zObjectAllocator.hpp --- 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 _used; ZPerCPU _undone; ZContended _shared_medium_page; ZPerCPU _shared_small_page; ZPerWorker _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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zPage.inline.hpp --- 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; } } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zRelocationSetSelector.cpp --- 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. diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zStat.cpp --- 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(); } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zStat.hpp --- 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(); }; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp --- 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(); + } } } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zWorkers.cpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/gc/z/zWorkers.hpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/interpreter/abstractInterpreter.cpp --- 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()); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/memory/freeList.hpp --- 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 FreeList { - friend class CompactibleFreeListSpace; friend class VMStructs; private: diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/memory/heap.cpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/memory/heap.hpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/memory/heapInspection.cpp --- 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); } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/memory/iterator.hpp --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/prims/jvmtiTagMap.cpp --- 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); } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/mutex.cpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/objectMonitor.cpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/objectMonitor.hpp --- 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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/objectMonitor.inline.hpp --- 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)); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/sharedRuntime.cpp --- 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()); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/synchronizer.cpp --- 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). diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/synchronizer.hpp --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/threadSMR.cpp --- 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); } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/runtime/vmStructs.cpp --- 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) \ diff -r b9bde9d224b9 -r 7567ce83f3b5 src/hotspot/share/services/heapDumper.cpp --- 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(); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java --- 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 diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java --- 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"); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java --- 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 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. * *

This method first verifies that this channel is open and that the diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- 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, 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, 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, Object> e : map.entrySet()) { + @SuppressWarnings("unchecked") + SocketOption option = (SocketOption) 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 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 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. */ diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java --- 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> groups = null; + // map multicast group to list of keys + private Map> groups; MembershipRegistry() { } @@ -116,16 +120,29 @@ } } + @FunctionalInterface + interface ThrowingConsumer { + void accept(T action) throws X; + } + + /** + * Invoke an action for each key in the registry + */ + + void forEach(ThrowingConsumer action) throws X { + if (groups != null) { + for (List 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); } } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/classes/sun/nio/ch/NativeDispatcher.java --- 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(); + } } diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java --- 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(); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/share/conf/security/java.security --- 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 # diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/unix/classes/sun/nio/ch/DatagramDispatcher.java --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c --- 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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.desktop/macosx/native/libawt_lwawt/awt/ImageSurfaceData.m --- 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); diff -r b9bde9d224b9 -r 7567ce83f3b5 src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterSurfaceData.m --- 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 @@ -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; diff -r b9bde9d224b9 -r 7567ce83f3b5 test/hotspot/jtreg/compiler/compilercontrol/CompilationModeHighOnlyTest.java --- 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:: * compiler.compilercontrol.CompilationModeHighOnlyTest * */ diff -r b9bde9d224b9 -r 7567ce83f3b5 test/hotspot/jtreg/gc/g1/TestGCLogMessages.java --- 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(); } } diff -r b9bde9d224b9 -r 7567ce83f3b5 test/hotspot/jtreg/gc/z/TestSmallHeap.java --- /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"); + } +} diff -r b9bde9d224b9 -r 7567ce83f3b5 test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java --- 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; } diff -r b9bde9d224b9 -r 7567ce83f3b5 test/hotspot/jtreg/runtime/Safepoint/NoSafepointVerifier.java --- 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); } } } diff -r b9bde9d224b9 -r 7567ce83f3b5 test/hotspot/jtreg/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java --- 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", diff -r b9bde9d224b9 -r 7567ce83f3b5 test/jdk/ProblemList.txt --- 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 ############################################################################ diff -r b9bde9d224b9 -r 7567ce83f3b5 test/jdk/com/sun/crypto/provider/KeyProtector/IterationCount.java --- /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 getBasicCommand() { + List cmd = new ArrayList<>(); + cmd.add(javaBinPath); + cmd.add("-cp"); + cmd.add(System.getProperty("test.classes", ".")); + return cmd; + } + + private static void executeCommand(List 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 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 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 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() { + + @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; + } + }); + } +} diff -r b9bde9d224b9 -r 7567ce83f3b5 test/jdk/java/nio/channels/DatagramChannel/AddressesAfterDisconnect.java --- 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"); - } - } - -} diff -r b9bde9d224b9 -r 7567ce83f3b5 test/jdk/java/nio/channels/DatagramChannel/AfterDisconnect.java --- /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, 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, Object> options(DatagramChannel dc) throws IOException { + Map, 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(); + } + } +} diff -r b9bde9d224b9 -r 7567ce83f3b5 test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java --- 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 { diff -r b9bde9d224b9 -r 7567ce83f3b5 test/langtools/tools/javac/processing/model/testgetallmembers/Main.java --- 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; diff -r b9bde9d224b9 -r 7567ce83f3b5 test/lib/jdk/test/lib/Platform.java --- 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"); } diff -r b9bde9d224b9 -r 7567ce83f3b5 test/lib/jdk/test/lib/cli/CommandLineOptionTest.java --- 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."); }