mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
Merge
This commit is contained in:
commit
ff93cf18a7
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +32,7 @@ formatVersion=3
|
||||
# Version of the currency code information in this class.
|
||||
# It is a serial number that accompanies with each amendment.
|
||||
|
||||
dataVersion=164
|
||||
dataVersion=167
|
||||
|
||||
# List of all valid ISO 4217 currency codes.
|
||||
# To ensure compatibility, do not remove codes.
|
||||
@ -47,7 +47,7 @@ all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036
|
||||
HRK191-HTG332-HUF348-IDR360-IEP372-ILS376-INR356-IQD368-IRR364-ISK352-\
|
||||
ITL380-JMD388-JOD400-JPY392-KES404-KGS417-KHR116-KMF174-KPW408-KRW410-\
|
||||
KWD414-KYD136-KZT398-LAK418-LBP422-LKR144-LRD430-LSL426-LTL440-LUF442-\
|
||||
LVL428-LYD434-MAD504-MDL498-MGA969-MGF450-MKD807-MMK104-MNT496-MOP446-MRO478-\
|
||||
LVL428-LYD434-MAD504-MDL498-MGA969-MGF450-MKD807-MMK104-MNT496-MOP446-MRO478-MRU929-\
|
||||
MTL470-MUR480-MVR462-MWK454-MXN484-MXV979-MYR458-MZM508-MZN943-NAD516-NGN566-\
|
||||
NIO558-NLG528-NOK578-NPR524-NZD554-OMR512-PAB590-PEN604-PGK598-PHP608-\
|
||||
PKR586-PLN985-PTE620-PYG600-QAR634-ROL946-RON946-RSD941-RUB643-RUR810-RWF646-SAR682-\
|
||||
@ -324,7 +324,7 @@ KG=KGS
|
||||
# LAO PEOPLE'S DEMOCRATIC REPUBLIC (THE)
|
||||
LA=LAK
|
||||
# LATVIA
|
||||
LV=LVL;2013-12-31-22-00-00;EUR
|
||||
LV=EUR
|
||||
# LEBANON
|
||||
LB=LBP
|
||||
# LESOTHO
|
||||
@ -336,7 +336,7 @@ LY=LYD
|
||||
# LIECHTENSTEIN
|
||||
LI=CHF
|
||||
# LITHUANIA
|
||||
LT=LTL;2014-12-31-22-00-00;EUR
|
||||
LT=EUR
|
||||
# LUXEMBOURG
|
||||
LU=EUR
|
||||
# MACAU
|
||||
@ -360,7 +360,7 @@ MH=USD
|
||||
# MARTINIQUE
|
||||
MQ=EUR
|
||||
# MAURITANIA
|
||||
MR=MRO
|
||||
MR=MRU
|
||||
# MAURITIUS
|
||||
MU=MUR
|
||||
# MAYOTTE
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
File-Date: 2017-08-15
|
||||
File-Date: 2018-04-23
|
||||
%%
|
||||
Type: language
|
||||
Subtag: aa
|
||||
@ -378,6 +378,7 @@ Subtag: hy
|
||||
Description: Armenian
|
||||
Added: 2005-10-16
|
||||
Suppress-Script: Armn
|
||||
Comments: see also hyw
|
||||
%%
|
||||
Type: language
|
||||
Subtag: hz
|
||||
@ -525,6 +526,7 @@ Suppress-Script: Latn
|
||||
%%
|
||||
Type: language
|
||||
Subtag: km
|
||||
Description: Khmer
|
||||
Description: Central Khmer
|
||||
Added: 2005-10-16
|
||||
Suppress-Script: Khmr
|
||||
@ -957,6 +959,7 @@ Subtag: sr
|
||||
Description: Serbian
|
||||
Added: 2005-10-16
|
||||
Macrolanguage: sh
|
||||
Comments: see cnr for Montenegrin
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ss
|
||||
@ -1531,6 +1534,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: add
|
||||
Description: Lidzonka
|
||||
Description: Dzodinka
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -2114,7 +2118,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: aja
|
||||
Description: Aja (Sudan)
|
||||
Description: Aja (South Sudan)
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -3097,6 +3101,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: asf
|
||||
Description: Auslan
|
||||
Description: Australian Sign Language
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -4240,7 +4245,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: bdh
|
||||
Description: Baka (Sudan)
|
||||
Description: Baka (South Sudan)
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -4250,6 +4255,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: bdj
|
||||
Description: Bai (South Sudan)
|
||||
Description: Bai
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -5293,7 +5299,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: blm
|
||||
Description: Beli (Sudan)
|
||||
Description: Beli (South Sudan)
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -8104,6 +8110,13 @@ Description: Con
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: cnr
|
||||
Description: Montenegrin
|
||||
Added: 2018-01-23
|
||||
Macrolanguage: sh
|
||||
Comments: see sr for Serbian
|
||||
%%
|
||||
Type: language
|
||||
Subtag: cns
|
||||
Description: Central Asmat
|
||||
Added: 2009-07-29
|
||||
@ -8768,6 +8781,11 @@ Description: Tepeuxila Cuicatec
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: cuy
|
||||
Description: Cuitlatec
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: cvg
|
||||
Description: Chug
|
||||
Added: 2009-07-29
|
||||
@ -11089,7 +11107,7 @@ Added: 2005-10-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: fap
|
||||
Description: Palor
|
||||
Description: Paloor
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -12282,6 +12300,11 @@ Description: Guya
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gkd
|
||||
Description: Magɨ (Madang Province)
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gke
|
||||
Description: Ndai
|
||||
Added: 2009-07-29
|
||||
@ -12494,6 +12517,11 @@ Description: Gooniyandi
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gnj
|
||||
Description: Ngen
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gnk
|
||||
Description: //Gana
|
||||
Description: ǁGana
|
||||
@ -13224,6 +13252,11 @@ Description: Guyanese Creole English
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gyo
|
||||
Description: Gyalsumdo
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gyr
|
||||
Description: Guarayu
|
||||
Added: 2009-07-29
|
||||
@ -13584,6 +13617,11 @@ Description: Hunjara-Kaina Ke
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: hkn
|
||||
Description: Mel-Khaonh
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: hks
|
||||
Description: Hong Kong Sign Language
|
||||
Description: Heung Kong Sau Yue
|
||||
@ -14238,6 +14276,12 @@ Description: Hya
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: hyw
|
||||
Description: Western Armenian
|
||||
Added: 2018-03-08
|
||||
Comments: see also hy
|
||||
%%
|
||||
Type: language
|
||||
Subtag: hyx
|
||||
Description: Armenian (family)
|
||||
Added: 2009-07-29
|
||||
@ -14860,6 +14904,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: iri
|
||||
Description: Rigwe
|
||||
Description: Irigwe
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -20313,7 +20358,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lno
|
||||
Description: Lango (Sudan)
|
||||
Description: Lango (South Sudan)
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -20579,6 +20624,7 @@ Type: language
|
||||
Subtag: lsg
|
||||
Description: Lyons Sign Language
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lsh
|
||||
@ -20850,6 +20896,11 @@ Description: Luwo
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lws
|
||||
Description: Malawian Sign Language
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lwt
|
||||
Description: Lewotobi
|
||||
Added: 2009-07-29
|
||||
@ -20904,6 +20955,7 @@ Type: language
|
||||
Subtag: maa
|
||||
Description: San Jerónimo Tecóatl Mazatec
|
||||
Added: 2009-07-29
|
||||
Comments: see also pbm
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mab
|
||||
@ -23799,11 +23851,13 @@ Type: language
|
||||
Subtag: mwx
|
||||
Description: Mediak
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mwy
|
||||
Description: Mosiro
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mwz
|
||||
@ -24527,6 +24581,8 @@ Type: language
|
||||
Subtag: ncp
|
||||
Description: Ndaktup
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2018-03-08
|
||||
Preferred-Value: kdz
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ncq
|
||||
@ -25458,6 +25514,11 @@ Description: Nihali
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nlm
|
||||
Description: Mankiyali
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nln
|
||||
Description: Durango Nahuatl
|
||||
Added: 2009-07-29
|
||||
@ -26693,6 +26754,11 @@ Description: Njebi
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nzd
|
||||
Description: Nzadi
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nzi
|
||||
Description: Nzima
|
||||
Added: 2005-10-16
|
||||
@ -27757,6 +27823,12 @@ Description: Mak (Nigeria)
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: pbm
|
||||
Description: Puebla Mazatec
|
||||
Added: 2018-03-08
|
||||
Comments: see also maa
|
||||
%%
|
||||
Type: language
|
||||
Subtag: pbn
|
||||
Description: Kpasam
|
||||
Added: 2009-07-29
|
||||
@ -30902,6 +30974,7 @@ Added: 2005-10-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: scp
|
||||
Description: Hyolmo
|
||||
Description: Helambu Sherpa
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -33049,6 +33122,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: sxg
|
||||
Description: Shuhi
|
||||
Description: Shixing
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -33835,6 +33909,11 @@ Description: Tulishi
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tez
|
||||
Description: Tetserret
|
||||
Added: 2018-03-08
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tfi
|
||||
Description: Tofin Gbe
|
||||
Added: 2009-07-29
|
||||
@ -34399,7 +34478,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: tlh
|
||||
Description: Klingon
|
||||
Description: tlhIngan-Hol
|
||||
Description: tlhIngan Hol
|
||||
Added: 2005-10-16
|
||||
%%
|
||||
Type: language
|
||||
@ -42199,6 +42278,7 @@ Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: asf
|
||||
Description: Auslan
|
||||
Description: Australian Sign Language
|
||||
Added: 2009-07-29
|
||||
Preferred-Value: asf
|
||||
@ -42927,7 +43007,7 @@ Type: extlang
|
||||
Subtag: lsg
|
||||
Description: Lyons Sign Language
|
||||
Added: 2009-07-29
|
||||
Preferred-Value: lsg
|
||||
Deprecated: 2018-03-08
|
||||
Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
@ -42983,6 +43063,13 @@ Prefix: lv
|
||||
Macrolanguage: lv
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: lws
|
||||
Description: Malawian Sign Language
|
||||
Added: 2018-03-08
|
||||
Preferred-Value: lws
|
||||
Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: lzh
|
||||
Description: Literary Chinese
|
||||
Added: 2009-07-29
|
||||
@ -44493,6 +44580,11 @@ Description: Kaganga
|
||||
Added: 2006-10-17
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Rohg
|
||||
Description: Hanifi Rohingya
|
||||
Added: 2017-12-13
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Roro
|
||||
Description: Rongorongo
|
||||
Added: 2005-10-16
|
||||
@ -44563,6 +44655,16 @@ Description: Sinhala
|
||||
Added: 2005-10-16
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Sogd
|
||||
Description: Sogdian
|
||||
Added: 2017-12-13
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Sogo
|
||||
Description: Old Sogdian
|
||||
Added: 2017-12-13
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Sora
|
||||
Description: Sora Sompeng
|
||||
Added: 2011-01-07
|
||||
@ -46412,15 +46514,26 @@ Comments: Portuguese orthography conventions established in 1990 but
|
||||
not brought into effect until 2009
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: aranes
|
||||
Description: Aranese
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in the Val d'Aran
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: arevela
|
||||
Description: Eastern Armenian
|
||||
Added: 2006-09-18
|
||||
Deprecated: 2018-03-24
|
||||
Preferred-Value: hy
|
||||
Prefix: hy
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: arevmda
|
||||
Description: Western Armenian
|
||||
Added: 2006-09-18
|
||||
Deprecated: 2018-03-24
|
||||
Preferred-Value: hyw
|
||||
Prefix: hy
|
||||
%%
|
||||
Type: variant
|
||||
@ -46431,6 +46544,13 @@ Added: 2017-06-05
|
||||
Prefix: tw
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: auvern
|
||||
Description: Auvergnat
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in Auvergne
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: baku1926
|
||||
Description: Unified Turkic Latin Alphabet (Historical)
|
||||
Added: 2007-04-18
|
||||
@ -46510,6 +46630,13 @@ Prefix: en
|
||||
Comments: Jargon embedded in American English
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: cisaup
|
||||
Description: Cisalpine
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in northwestern Italy
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: colb1945
|
||||
Description: Portuguese-Brazilian Orthographic Convention of 1945
|
||||
(Convenção Ortográfica Luso-Brasileira de 1945)
|
||||
@ -46528,6 +46655,12 @@ Added: 2015-12-07
|
||||
Prefix: en
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: creiss
|
||||
Description: Occitan variants of the Croissant area
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: dajnko
|
||||
Description: Slovene in Dajnko alphabet
|
||||
Added: 2012-06-27
|
||||
@ -46556,6 +46689,11 @@ Description: International Phonetic Alphabet
|
||||
Added: 2006-12-11
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: fonkirsh
|
||||
Description: Kirshenbaum Phonetic Alphabet
|
||||
Added: 2018-04-22
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: fonnapa
|
||||
Description: North American Phonetic Alphabet
|
||||
Description: Americanist Phonetic Notation
|
||||
@ -46573,6 +46711,36 @@ Added: 2010-10-23
|
||||
Comments: Indicates that the content is transcribed according to X-SAMPA
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: gascon
|
||||
Description: Gascon
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in Gascony
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: grclass
|
||||
Description: Classical Occitan orthography
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Classical written standard for Occitan developed in 1935 by
|
||||
Alibèrt
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: grital
|
||||
Description: Italian-inspired Occitan orthography
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: grmistr
|
||||
Description: Mistralian or Mistralian-inspired Occitan orthography
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Written standard developed by Romanilha in 1853 and used by
|
||||
Mistral and the Félibres, including derived standards such as Escolo
|
||||
dóu Po, Escolo Gaston Febus, and others
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: hepburn
|
||||
Description: Hepburn romanization
|
||||
Added: 2009-10-01
|
||||
@ -46617,6 +46785,13 @@ Added: 2010-07-28
|
||||
Prefix: sa
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: ivanchov
|
||||
Description: Bulgarian in 1899 orthography
|
||||
Added: 2017-12-13
|
||||
Prefix: bg
|
||||
Comments: Bulgarian orthography introduced by Todor Ivanchov in 1899
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: jauer
|
||||
Description: Jauer dialect of Romansh
|
||||
Added: 2010-06-29
|
||||
@ -46659,6 +46834,20 @@ Added: 2010-07-28
|
||||
Prefix: sa
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: lemosin
|
||||
Description: Limousin
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in Limousin
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: lengadoc
|
||||
Description: Languedocien
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in Languedoc
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: lipaw
|
||||
Description: The Lipovaz dialect of Resian
|
||||
Description: The Lipovec dialect of Resian
|
||||
@ -46712,6 +46901,13 @@ Added: 2015-11-25
|
||||
Prefix: en-CA
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: nicard
|
||||
Description: Niçard
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in Nice
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: njiva
|
||||
Description: The Gniva dialect of Resian
|
||||
Description: The Njiva dialect of Resian
|
||||
@ -46798,6 +46994,13 @@ Added: 2006-12-11
|
||||
Prefix: el
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: provenc
|
||||
Description: Provençal
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in Provence
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: puter
|
||||
Description: Puter idiom of Romansh
|
||||
Added: 2010-06-29
|
||||
@ -46959,6 +47162,13 @@ Comments: Vallader is one of the five traditional written standards or
|
||||
"idioms" of the Romansh language.
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: vivaraup
|
||||
Description: Vivaro-Alpine
|
||||
Added: 2018-04-22
|
||||
Prefix: oc
|
||||
Comments: Occitan variant spoken in northeastern Occitania
|
||||
%%
|
||||
Type: variant
|
||||
Subtag: wadegile
|
||||
Description: Wade-Giles romanization
|
||||
Added: 2008-10-03
|
||||
|
||||
@ -2967,6 +2967,7 @@ class Assembler : public AbstractAssembler {
|
||||
|
||||
// branch never (nop)
|
||||
inline void z_nop();
|
||||
inline void nop(); // Used by shared code.
|
||||
|
||||
// ===============================================================================================
|
||||
|
||||
|
||||
@ -1311,6 +1311,7 @@ inline void Assembler::z_clgij(Register r1, int64_t i2, branch_condition m3, Lab
|
||||
|
||||
// branch never (nop), branch always
|
||||
inline void Assembler::z_nop() { z_bcr(bcondNop, Z_R0); }
|
||||
inline void Assembler::nop() { z_nop(); }
|
||||
inline void Assembler::z_br(Register r2) { assert(r2 != Z_R0, "nop if target is Z_R0, use z_nop() instead"); z_bcr(bcondAlways, r2 ); }
|
||||
|
||||
inline void Assembler::z_exrl(Register r1, Label& L) { z_exrl(r1, target(L)); } // z10
|
||||
|
||||
@ -95,8 +95,6 @@
|
||||
void invalidate_registers(Register preserve1 = noreg, Register preserve2 = noreg,
|
||||
Register preserve3 = noreg) PRODUCT_RETURN;
|
||||
|
||||
void nop() { z_nop(); }
|
||||
|
||||
// This platform only uses signal-based null checks. The Label is not needed.
|
||||
void null_check(Register r, Label *Lnull = NULL) { MacroAssembler::null_check(r); }
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
|
||||
bool on_heap = (decorators & IN_HEAP) != 0;
|
||||
bool on_root = (decorators & IN_ROOT) != 0;
|
||||
bool oop_not_null = (decorators & OOP_NOT_NULL) != 0;
|
||||
bool atomic = (decorators & MO_RELAXED) != 0;
|
||||
|
||||
switch (type) {
|
||||
case T_OBJECT:
|
||||
@ -58,6 +59,37 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_BOOLEAN: __ load_unsigned_byte(dst, src); break;
|
||||
case T_BYTE: __ load_signed_byte(dst, src); break;
|
||||
case T_CHAR: __ load_unsigned_short(dst, src); break;
|
||||
case T_SHORT: __ load_signed_short(dst, src); break;
|
||||
case T_INT: __ movl (dst, src); break;
|
||||
case T_ADDRESS: __ movptr(dst, src); break;
|
||||
case T_FLOAT:
|
||||
assert(dst == noreg, "only to ftos");
|
||||
__ load_float(src);
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(dst == noreg, "only to dtos");
|
||||
__ load_double(src);
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(dst == noreg, "only to ltos");
|
||||
#ifdef _LP64
|
||||
__ movq(rax, src);
|
||||
#else
|
||||
if (atomic) {
|
||||
__ fild_d(src); // Must load atomically
|
||||
__ subptr(rsp,2*wordSize); // Make space for store
|
||||
__ fistp_d(Address(rsp,0));
|
||||
__ pop(rax);
|
||||
__ pop(rdx);
|
||||
} else {
|
||||
__ movl(rax, src);
|
||||
__ movl(rdx, src.plus_disp(wordSize));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default: Unimplemented();
|
||||
}
|
||||
}
|
||||
@ -67,6 +99,7 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
|
||||
bool on_heap = (decorators & IN_HEAP) != 0;
|
||||
bool on_root = (decorators & IN_ROOT) != 0;
|
||||
bool oop_not_null = (decorators & OOP_NOT_NULL) != 0;
|
||||
bool atomic = (decorators & MO_RELAXED) != 0;
|
||||
|
||||
switch (type) {
|
||||
case T_OBJECT:
|
||||
@ -106,6 +139,50 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_BOOLEAN:
|
||||
__ andl(val, 0x1); // boolean is true if LSB is 1
|
||||
__ movb(dst, val);
|
||||
break;
|
||||
case T_BYTE:
|
||||
__ movb(dst, val);
|
||||
break;
|
||||
case T_SHORT:
|
||||
__ movw(dst, val);
|
||||
break;
|
||||
case T_CHAR:
|
||||
__ movw(dst, val);
|
||||
break;
|
||||
case T_INT:
|
||||
__ movl(dst, val);
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(val == noreg, "only tos");
|
||||
#ifdef _LP64
|
||||
__ movq(dst, rax);
|
||||
#else
|
||||
if (atomic) {
|
||||
__ push(rdx);
|
||||
__ push(rax); // Must update atomically with FIST
|
||||
__ fild_d(Address(rsp,0)); // So load into FPU register
|
||||
__ fistp_d(dst); // and put into memory atomically
|
||||
__ addptr(rsp, 2*wordSize);
|
||||
} else {
|
||||
__ movptr(dst, rax);
|
||||
__ movptr(dst.plus_disp(wordSize), rdx);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case T_FLOAT:
|
||||
assert(val == noreg, "only tos");
|
||||
__ store_float(dst);
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
assert(val == noreg, "only tos");
|
||||
__ store_double(dst);
|
||||
break;
|
||||
case T_ADDRESS:
|
||||
__ movptr(dst, val);
|
||||
break;
|
||||
default: Unimplemented();
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +175,9 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
|
||||
__ verify_oop(method_temp);
|
||||
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
|
||||
__ verify_oop(method_temp);
|
||||
__ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, method_temp,
|
||||
Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())),
|
||||
noreg, noreg);
|
||||
|
||||
if (VerifyMethodHandles && !for_compiler_entry) {
|
||||
// make sure recv is already on stack
|
||||
@ -390,7 +392,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
|
||||
}
|
||||
__ load_heap_oop(rbx_method, member_vmtarget);
|
||||
__ movptr(rbx_method, vmtarget_method);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg);
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_linkToStatic:
|
||||
@ -398,7 +400,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
|
||||
}
|
||||
__ load_heap_oop(rbx_method, member_vmtarget);
|
||||
__ movptr(rbx_method, vmtarget_method);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg);
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_linkToVirtual:
|
||||
@ -412,7 +414,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
|
||||
// pick out the vtable index from the MemberName, and then we can discard it:
|
||||
Register temp2_index = temp2;
|
||||
__ movptr(temp2_index, member_vmindex);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg);
|
||||
|
||||
if (VerifyMethodHandles) {
|
||||
Label L_index_ok;
|
||||
@ -446,7 +448,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
__ verify_klass_ptr(temp3_intf);
|
||||
|
||||
Register rbx_index = rbx_method;
|
||||
__ movptr(rbx_index, member_vmindex);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_index, member_vmindex, noreg, noreg);
|
||||
if (VerifyMethodHandles) {
|
||||
Label L;
|
||||
__ cmpl(rbx_index, 0);
|
||||
|
||||
@ -770,9 +770,10 @@ void TemplateTable::iaload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ movl(rax, Address(rdx, rax,
|
||||
Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||
__ access_load_at(T_INT, IN_HEAP | IN_HEAP_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_INT)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::laload() {
|
||||
@ -782,8 +783,10 @@ void TemplateTable::laload() {
|
||||
index_check(rdx, rax); // kills rbx
|
||||
NOT_LP64(__ mov(rbx, rax));
|
||||
// rbx,: index
|
||||
__ movptr(rax, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize));
|
||||
NOT_LP64(__ movl(rdx, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize)));
|
||||
__ access_load_at(T_LONG, IN_HEAP | IN_HEAP_ARRAY, noreg /* ltos */,
|
||||
Address(rdx, rbx, Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_LONG)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
|
||||
@ -793,9 +796,11 @@ void TemplateTable::faload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ load_float(Address(rdx, rax,
|
||||
Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
|
||||
__ access_load_at(T_FLOAT, IN_HEAP | IN_HEAP_ARRAY, noreg /* ftos */,
|
||||
Address(rdx, rax,
|
||||
Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_FLOAT)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::daload() {
|
||||
@ -803,9 +808,11 @@ void TemplateTable::daload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ load_double(Address(rdx, rax,
|
||||
Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP | IN_HEAP_ARRAY, noreg /* dtos */,
|
||||
Address(rdx, rax,
|
||||
Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_DOUBLE)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::aaload() {
|
||||
@ -826,7 +833,9 @@ void TemplateTable::baload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ load_signed_byte(rax, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
|
||||
__ access_load_at(T_BYTE, IN_HEAP | IN_HEAP_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::caload() {
|
||||
@ -834,7 +843,9 @@ void TemplateTable::caload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
|
||||
__ access_load_at(T_CHAR, IN_HEAP | IN_HEAP_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
// iload followed by caload frequent pair
|
||||
@ -847,10 +858,9 @@ void TemplateTable::fast_icaload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ load_unsigned_short(rax,
|
||||
Address(rdx, rax,
|
||||
Address::times_2,
|
||||
arrayOopDesc::base_offset_in_bytes(T_CHAR)));
|
||||
__ access_load_at(T_CHAR, IN_HEAP | IN_HEAP_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
|
||||
@ -859,7 +869,9 @@ void TemplateTable::saload() {
|
||||
// rax: index
|
||||
// rdx: array
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ load_signed_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT)));
|
||||
__ access_load_at(T_SHORT, IN_HEAP | IN_HEAP_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT)),
|
||||
noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::iload(int n) {
|
||||
@ -1051,10 +1063,10 @@ void TemplateTable::iastore() {
|
||||
// rbx: index
|
||||
// rdx: array
|
||||
index_check(rdx, rbx); // prefer index in rbx
|
||||
__ movl(Address(rdx, rbx,
|
||||
Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_INT)),
|
||||
rax);
|
||||
__ access_store_at(T_INT, IN_HEAP | IN_HEAP_ARRAY,
|
||||
Address(rdx, rbx, Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_INT)),
|
||||
rax, noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::lastore() {
|
||||
@ -1065,8 +1077,10 @@ void TemplateTable::lastore() {
|
||||
// rdx: high(value)
|
||||
index_check(rcx, rbx); // prefer index in rbx,
|
||||
// rbx,: index
|
||||
__ movptr(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize), rax);
|
||||
NOT_LP64(__ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize), rdx));
|
||||
__ access_store_at(T_LONG, IN_HEAP | IN_HEAP_ARRAY,
|
||||
Address(rcx, rbx, Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_LONG)),
|
||||
noreg /* ltos */, noreg, noreg);
|
||||
}
|
||||
|
||||
|
||||
@ -1077,7 +1091,10 @@ void TemplateTable::fastore() {
|
||||
// rbx: index
|
||||
// rdx: array
|
||||
index_check(rdx, rbx); // prefer index in rbx
|
||||
__ store_float(Address(rdx, rbx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
|
||||
__ access_store_at(T_FLOAT, IN_HEAP | IN_HEAP_ARRAY,
|
||||
Address(rdx, rbx, Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_FLOAT)),
|
||||
noreg /* ftos */, noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::dastore() {
|
||||
@ -1087,7 +1104,10 @@ void TemplateTable::dastore() {
|
||||
// rbx: index
|
||||
// rdx: array
|
||||
index_check(rdx, rbx); // prefer index in rbx
|
||||
__ store_double(Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
|
||||
__ access_store_at(T_DOUBLE, IN_HEAP | IN_HEAP_ARRAY,
|
||||
Address(rdx, rbx, Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_DOUBLE)),
|
||||
noreg /* dtos */, noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::aastore() {
|
||||
@ -1160,10 +1180,10 @@ void TemplateTable::bastore() {
|
||||
__ jccb(Assembler::zero, L_skip);
|
||||
__ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1
|
||||
__ bind(L_skip);
|
||||
__ movb(Address(rdx, rbx,
|
||||
Address::times_1,
|
||||
arrayOopDesc::base_offset_in_bytes(T_BYTE)),
|
||||
rax);
|
||||
__ access_store_at(T_BYTE, IN_HEAP | IN_HEAP_ARRAY,
|
||||
Address(rdx, rbx,Address::times_1,
|
||||
arrayOopDesc::base_offset_in_bytes(T_BYTE)),
|
||||
rax, noreg, noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::castore() {
|
||||
@ -1173,10 +1193,10 @@ void TemplateTable::castore() {
|
||||
// rbx: index
|
||||
// rdx: array
|
||||
index_check(rdx, rbx); // prefer index in rbx
|
||||
__ movw(Address(rdx, rbx,
|
||||
Address::times_2,
|
||||
arrayOopDesc::base_offset_in_bytes(T_CHAR)),
|
||||
rax);
|
||||
__ access_store_at(T_CHAR, IN_HEAP | IN_HEAP_ARRAY,
|
||||
Address(rdx, rbx, Address::times_2,
|
||||
arrayOopDesc::base_offset_in_bytes(T_CHAR)),
|
||||
rax, noreg, noreg);
|
||||
}
|
||||
|
||||
|
||||
@ -2852,7 +2872,6 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
|
||||
const Address field(obj, off, Address::times_1, 0*wordSize);
|
||||
NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize));
|
||||
|
||||
Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
|
||||
|
||||
@ -2864,7 +2883,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
__ jcc(Assembler::notZero, notByte);
|
||||
// btos
|
||||
__ load_signed_byte(rax, field);
|
||||
__ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ push(btos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2877,7 +2896,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ jcc(Assembler::notEqual, notBool);
|
||||
|
||||
// ztos (same code as btos)
|
||||
__ load_signed_byte(rax, field);
|
||||
__ access_load_at(T_BOOLEAN, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ push(ztos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2901,7 +2920,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(flags, itos);
|
||||
__ jcc(Assembler::notEqual, notInt);
|
||||
// itos
|
||||
__ movl(rax, field);
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ push(itos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2913,7 +2932,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(flags, ctos);
|
||||
__ jcc(Assembler::notEqual, notChar);
|
||||
// ctos
|
||||
__ load_unsigned_short(rax, field);
|
||||
__ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ push(ctos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2925,7 +2944,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(flags, stos);
|
||||
__ jcc(Assembler::notEqual, notShort);
|
||||
// stos
|
||||
__ load_signed_short(rax, field);
|
||||
__ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ push(stos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2937,19 +2956,9 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(flags, ltos);
|
||||
__ jcc(Assembler::notEqual, notLong);
|
||||
// ltos
|
||||
|
||||
#ifndef _LP64
|
||||
// Generate code as if volatile. There just aren't enough registers to
|
||||
// save that information and this code is faster than the test.
|
||||
__ fild_d(field); // Must load atomically
|
||||
__ subptr(rsp,2*wordSize); // Make space for store
|
||||
__ fistp_d(Address(rsp,0));
|
||||
__ pop(rax);
|
||||
__ pop(rdx);
|
||||
#else
|
||||
__ movq(rax, field);
|
||||
#endif
|
||||
|
||||
// Generate code as if volatile (x86_32). There just aren't enough registers to
|
||||
// save that information and this code is faster than the test.
|
||||
__ access_load_at(T_LONG, IN_HEAP | MO_RELAXED, noreg /* ltos */, field, noreg, noreg);
|
||||
__ push(ltos);
|
||||
// Rewrite bytecode to be faster
|
||||
LP64_ONLY(if (!is_static && rc == may_rewrite) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx));
|
||||
@ -2960,7 +2969,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ jcc(Assembler::notEqual, notFloat);
|
||||
// ftos
|
||||
|
||||
__ load_float(field);
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
|
||||
__ push(ftos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2974,7 +2983,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ jcc(Assembler::notEqual, notDouble);
|
||||
#endif
|
||||
// dtos
|
||||
__ load_double(field);
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, field, noreg, noreg);
|
||||
__ push(dtos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -3133,7 +3142,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(btos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ movb(field, rax);
|
||||
__ access_store_at(T_BYTE, IN_HEAP, field, rax, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3148,8 +3157,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(ztos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ andl(rax, 0x1);
|
||||
__ movb(field, rax);
|
||||
__ access_store_at(T_BOOLEAN, IN_HEAP, field, rax, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3180,7 +3188,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(itos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ movl(field, rax);
|
||||
__ access_store_at(T_INT, IN_HEAP, field, rax, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3195,7 +3203,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(ctos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ movw(field, rax);
|
||||
__ access_store_at(T_CHAR, IN_HEAP, field, rax, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3210,7 +3218,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(stos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ movw(field, rax);
|
||||
__ access_store_at(T_SHORT, IN_HEAP, field, rax, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3226,7 +3234,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(ltos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ movq(field, rax);
|
||||
__ access_store_at(T_LONG, IN_HEAP, field, noreg /* ltos*/, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3242,11 +3250,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
|
||||
// Replace with real volatile test
|
||||
__ push(rdx);
|
||||
__ push(rax); // Must update atomically with FIST
|
||||
__ fild_d(Address(rsp,0)); // So load into FPU register
|
||||
__ fistp_d(field); // and put into memory atomically
|
||||
__ addptr(rsp, 2*wordSize);
|
||||
__ access_store_at(T_LONG, IN_HEAP | MO_RELAXED, field, noreg /* ltos */, noreg, noreg);
|
||||
// volatile_barrier();
|
||||
volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
|
||||
Assembler::StoreStore));
|
||||
@ -3257,8 +3261,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
__ pop(ltos); // overwrites rdx
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ movptr(hi, rdx);
|
||||
__ movptr(field, rax);
|
||||
__ access_store_at(T_LONG, IN_HEAP, field, noreg /* ltos */, noreg, noreg);
|
||||
// Don't rewrite to _fast_lputfield for potential volatile case.
|
||||
__ jmp(notVolatile);
|
||||
}
|
||||
@ -3272,7 +3275,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(ftos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ store_float(field);
|
||||
__ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos */, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3289,7 +3292,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
{
|
||||
__ pop(dtos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ store_double(field);
|
||||
__ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* dtos */, noreg, noreg);
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
|
||||
}
|
||||
@ -3422,30 +3425,31 @@ void TemplateTable::fast_storefield(TosState state) {
|
||||
break;
|
||||
case Bytecodes::_fast_lputfield:
|
||||
#ifdef _LP64
|
||||
__ movq(field, rax);
|
||||
__ access_store_at(T_LONG, IN_HEAP, field, noreg /* ltos */, noreg, noreg);
|
||||
#else
|
||||
__ stop("should not be rewritten");
|
||||
#endif
|
||||
break;
|
||||
case Bytecodes::_fast_iputfield:
|
||||
__ movl(field, rax);
|
||||
__ access_store_at(T_INT, IN_HEAP, field, rax, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_zputfield:
|
||||
__ andl(rax, 0x1); // boolean is true if LSB is 1
|
||||
// fall through to bputfield
|
||||
__ access_store_at(T_BOOLEAN, IN_HEAP, field, rax, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_bputfield:
|
||||
__ movb(field, rax);
|
||||
__ access_store_at(T_BYTE, IN_HEAP, field, rax, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_sputfield:
|
||||
// fall through
|
||||
__ access_store_at(T_SHORT, IN_HEAP, field, rax, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_cputfield:
|
||||
__ movw(field, rax);
|
||||
__ access_store_at(T_CHAR, IN_HEAP, field, rax, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_fputfield:
|
||||
__ store_float(field);
|
||||
__ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos*/, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_dputfield:
|
||||
__ store_double(field);
|
||||
__ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* dtos*/, noreg, noreg);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -3512,28 +3516,28 @@ void TemplateTable::fast_accessfield(TosState state) {
|
||||
break;
|
||||
case Bytecodes::_fast_lgetfield:
|
||||
#ifdef _LP64
|
||||
__ movq(rax, field);
|
||||
__ access_load_at(T_LONG, IN_HEAP, noreg /* ltos */, field, noreg, noreg);
|
||||
#else
|
||||
__ stop("should not be rewritten");
|
||||
#endif
|
||||
break;
|
||||
case Bytecodes::_fast_igetfield:
|
||||
__ movl(rax, field);
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_bgetfield:
|
||||
__ movsbl(rax, field);
|
||||
__ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_sgetfield:
|
||||
__ load_signed_short(rax, field);
|
||||
__ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_cgetfield:
|
||||
__ load_unsigned_short(rax, field);
|
||||
__ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_fgetfield:
|
||||
__ load_float(field);
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_dgetfield:
|
||||
__ load_double(field);
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, field, noreg, noreg);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -3566,14 +3570,14 @@ void TemplateTable::fast_xaccess(TosState state) {
|
||||
const Address field = Address(rax, rbx, Address::times_1, 0*wordSize);
|
||||
switch (state) {
|
||||
case itos:
|
||||
__ movl(rax, field);
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg);
|
||||
break;
|
||||
case atos:
|
||||
do_oop_load(_masm, field, rax);
|
||||
__ verify_oop(rax);
|
||||
break;
|
||||
case ftos:
|
||||
__ load_float(field);
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
|
||||
@ -75,7 +75,7 @@ address* AOTCompiledMethod::orig_pc_addr(const frame* fr) {
|
||||
return (address*) ((address)fr->unextended_sp() + _meta->orig_pc_offset());
|
||||
}
|
||||
|
||||
bool AOTCompiledMethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred) {
|
||||
bool AOTCompiledMethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ bool AOTCompiledMethod::make_entrant() {
|
||||
// more conservative than for nmethods.
|
||||
void AOTCompiledMethod::flush_evol_dependents_on(InstanceKlass* dependee) {
|
||||
if (is_java_method()) {
|
||||
cleanup_inline_caches();
|
||||
clear_inline_caches();
|
||||
mark_for_deoptimization();
|
||||
make_not_entrant();
|
||||
}
|
||||
|
||||
@ -284,8 +284,8 @@ private:
|
||||
bool is_aot_runtime_stub() const { return _method == NULL; }
|
||||
|
||||
protected:
|
||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
virtual bool do_unloading_jvmci(bool unloading_occurred) { return false; }
|
||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive);
|
||||
virtual bool do_unloading_jvmci() { return false; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -4257,7 +4257,7 @@ int java_lang_AssertionStatusDirectives::packages_offset;
|
||||
int java_lang_AssertionStatusDirectives::packageEnabled_offset;
|
||||
int java_lang_AssertionStatusDirectives::deflt_offset;
|
||||
int java_nio_Buffer::_limit_offset;
|
||||
int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset = 0;
|
||||
int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset;
|
||||
int reflect_ConstantPool::_oop_offset;
|
||||
int reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
|
||||
|
||||
@ -4399,13 +4399,12 @@ void java_nio_Buffer::serialize(SerializeClosure* f) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
|
||||
if (_owner_offset != 0) return;
|
||||
#define AOS_FIELDS_DO(macro) \
|
||||
macro(_owner_offset, k, "exclusiveOwnerThread", thread_signature, false)
|
||||
|
||||
SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK);
|
||||
InstanceKlass* k = SystemDictionary::abstract_ownable_synchronizer_klass();
|
||||
compute_offset(_owner_offset, k,
|
||||
"exclusiveOwnerThread", vmSymbols::thread_signature());
|
||||
void java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass();
|
||||
AOS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
oop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(oop obj) {
|
||||
@ -4473,6 +4472,7 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_StackTraceElement::compute_offsets();
|
||||
java_lang_StackFrameInfo::compute_offsets();
|
||||
java_lang_LiveStackFrameInfo::compute_offsets();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets();
|
||||
|
||||
// generated interpreter code wants to know about the offsets we just computed:
|
||||
AbstractAssembler::update_delayed_values();
|
||||
|
||||
@ -1483,7 +1483,7 @@ class java_util_concurrent_locks_AbstractOwnableSynchronizer : AllStatic {
|
||||
private:
|
||||
static int _owner_offset;
|
||||
public:
|
||||
static void initialize(TRAPS);
|
||||
static void compute_offsets();
|
||||
static oop get_owner_threadObj(oop obj);
|
||||
};
|
||||
|
||||
|
||||
@ -110,9 +110,6 @@ oop SystemDictionary::_java_platform_loader = NULL;
|
||||
|
||||
bool SystemDictionary::_has_checkPackageAccess = false;
|
||||
|
||||
// lazily initialized klass variables
|
||||
InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
|
||||
|
||||
// Default ProtectionDomainCacheSize value
|
||||
|
||||
const int defaultProtectionDomainCacheSize = 1009;
|
||||
@ -1896,22 +1893,6 @@ void SystemDictionary::remove_classes_in_error_state() {
|
||||
ClassLoaderDataGraph::cld_do(&rcc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Lazily load klasses
|
||||
|
||||
void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
|
||||
// if multiple threads calling this function, only one thread will load
|
||||
// the class. The other threads will find the loaded version once the
|
||||
// class is loaded.
|
||||
Klass* aos = _abstract_ownable_synchronizer_klass;
|
||||
if (aos == NULL) {
|
||||
Klass* k = resolve_or_fail(vmSymbols::java_util_concurrent_locks_AbstractOwnableSynchronizer(), true, CHECK);
|
||||
// Force a fence to prevent any read before the write completes
|
||||
OrderAccess::fence();
|
||||
_abstract_ownable_synchronizer_klass = InstanceKlass::cast(k);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
|
||||
|
||||
@ -199,6 +199,9 @@ class OopStorage;
|
||||
do_klass(StackFrameInfo_klass, java_lang_StackFrameInfo, Opt ) \
|
||||
do_klass(LiveStackFrameInfo_klass, java_lang_LiveStackFrameInfo, Opt ) \
|
||||
\
|
||||
/* support for stack dump lock analysis */ \
|
||||
do_klass(java_util_concurrent_locks_AbstractOwnableSynchronizer_klass, java_util_concurrent_locks_AbstractOwnableSynchronizer, Pre ) \
|
||||
\
|
||||
/* Preload boxing klasses */ \
|
||||
do_klass(Boolean_klass, java_lang_Boolean, Pre ) \
|
||||
do_klass(Character_klass, java_lang_Character, Pre ) \
|
||||
@ -449,12 +452,6 @@ public:
|
||||
}
|
||||
static BasicType box_klass_type(Klass* k); // inverse of box_klass
|
||||
|
||||
// methods returning lazily loaded klasses
|
||||
// The corresponding method to load the class must be called before calling them.
|
||||
static InstanceKlass* abstract_ownable_synchronizer_klass() { return check_klass(_abstract_ownable_synchronizer_klass); }
|
||||
|
||||
static void load_abstract_ownable_synchronizer_klass(TRAPS);
|
||||
|
||||
protected:
|
||||
// Returns the class loader data to be used when looking up/updating the
|
||||
// system dictionary.
|
||||
@ -729,9 +726,6 @@ protected:
|
||||
// Variables holding commonly used klasses (preloaded)
|
||||
static InstanceKlass* _well_known_klasses[];
|
||||
|
||||
// Lazily loaded klasses
|
||||
static InstanceKlass* volatile _abstract_ownable_synchronizer_klass;
|
||||
|
||||
// table of box klasses (int_klass, etc.)
|
||||
static InstanceKlass* _box_klasses[T_VOID+1];
|
||||
|
||||
|
||||
@ -685,8 +685,15 @@ void CodeCache::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurre
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
CompiledMethodIterator iter;
|
||||
while(iter.next_alive()) {
|
||||
iter.method()->do_unloading(is_alive, unloading_occurred);
|
||||
iter.method()->do_unloading(is_alive);
|
||||
}
|
||||
|
||||
// Now that all the unloaded nmethods are known, cleanup caches
|
||||
// before CLDG is purged.
|
||||
// This is another code cache walk but it is moved from gc_epilogue.
|
||||
// G1 does a parallel walk of the nmethods so cleans them up
|
||||
// as it goes and doesn't call this.
|
||||
do_unloading_nmethod_caches(unloading_occurred);
|
||||
}
|
||||
|
||||
void CodeCache::blobs_do(CodeBlobClosure* f) {
|
||||
@ -720,8 +727,11 @@ void CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure* f) {
|
||||
assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
|
||||
|
||||
bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
|
||||
if (TraceScavenge) {
|
||||
cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
|
||||
LogTarget(Trace, gc, nmethod) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
CompileTask::print(&ls, cur,
|
||||
is_live ? "scavenge root " : "dead scavenge root", /*short_form:*/ true);
|
||||
}
|
||||
if (is_live) {
|
||||
// Perform cur->oops_do(f), maybe just once per nmethod.
|
||||
@ -892,18 +902,26 @@ void CodeCache::verify_icholder_relocations() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeCache::gc_prologue() {
|
||||
}
|
||||
void CodeCache::gc_prologue() { }
|
||||
|
||||
void CodeCache::gc_epilogue() {
|
||||
prune_scavenge_root_nmethods();
|
||||
}
|
||||
|
||||
|
||||
void CodeCache::do_unloading_nmethod_caches(bool class_unloading_occurred) {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
NOT_DEBUG(if (needs_cache_clean())) {
|
||||
// Even if classes are not unloaded, there may have been some nmethods that are
|
||||
// unloaded because oops in them are no longer reachable.
|
||||
NOT_DEBUG(if (needs_cache_clean() || class_unloading_occurred)) {
|
||||
CompiledMethodIterator iter;
|
||||
while(iter.next_alive()) {
|
||||
CompiledMethod* cm = iter.method();
|
||||
assert(!cm->is_unloaded(), "Tautology");
|
||||
DEBUG_ONLY(if (needs_cache_clean())) {
|
||||
cm->cleanup_inline_caches();
|
||||
DEBUG_ONLY(if (needs_cache_clean() || class_unloading_occurred)) {
|
||||
// Clean up both unloaded klasses from nmethods and unloaded nmethods
|
||||
// from inline caches.
|
||||
cm->unload_nmethod_caches(/*parallel*/false, class_unloading_occurred);
|
||||
}
|
||||
DEBUG_ONLY(cm->verify());
|
||||
DEBUG_ONLY(cm->verify_oop_relocations());
|
||||
@ -911,8 +929,6 @@ void CodeCache::gc_epilogue() {
|
||||
}
|
||||
|
||||
set_needs_cache_clean(false);
|
||||
prune_scavenge_root_nmethods();
|
||||
|
||||
verify_icholder_relocations();
|
||||
}
|
||||
|
||||
|
||||
@ -168,9 +168,10 @@ class CodeCache : AllStatic {
|
||||
static void gc_epilogue();
|
||||
static void gc_prologue();
|
||||
static void verify_oops();
|
||||
// If "unloading_occurred" is true, then unloads (i.e., breaks root links
|
||||
// If any oops are not marked this method unloads (i.e., breaks root links
|
||||
// to) any unmarked codeBlobs in the cache. Sets "marked_for_unloading"
|
||||
// to "true" iff some code got unloaded.
|
||||
// "unloading_occurred" controls whether metadata should be cleaned because of class unloading.
|
||||
static void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN;
|
||||
|
||||
@ -223,8 +224,10 @@ class CodeCache : AllStatic {
|
||||
|
||||
static bool needs_cache_clean() { return _needs_cache_clean; }
|
||||
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
|
||||
|
||||
static void clear_inline_caches(); // clear all inline caches
|
||||
static void cleanup_inline_caches();
|
||||
static void cleanup_inline_caches(); // clean unloaded/zombie nmethods from inline caches
|
||||
static void do_unloading_nmethod_caches(bool class_unloading_occurred); // clean all nmethod caches for unloading, including inline caches
|
||||
|
||||
// Returns true if an own CodeHeap for the given CodeBlobType is available
|
||||
static bool heap_available(int code_blob_type);
|
||||
|
||||
@ -552,7 +552,8 @@ void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site, const Com
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void CompiledStaticCall::set_to_clean() {
|
||||
void CompiledStaticCall::set_to_clean(bool in_use) {
|
||||
// in_use is unused but needed to match template function in CompiledMethod
|
||||
assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
|
||||
// Reset call site
|
||||
MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
|
||||
|
||||
@ -358,7 +358,7 @@ public:
|
||||
virtual address destination() const = 0;
|
||||
|
||||
// Clean static call (will force resolving on next use)
|
||||
void set_to_clean();
|
||||
void set_to_clean(bool in_use = true);
|
||||
|
||||
// Set state. The entry must be the same, as computed by compute_entry.
|
||||
// Computation and setting is split up, since the actions are separate during
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
#include "code/scopeDesc.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "interpreter/bytecode.inline.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logTag.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
#include "oops/method.inline.hpp"
|
||||
@ -222,9 +224,7 @@ ScopeDesc* CompiledMethod::scope_desc_near(address pc) {
|
||||
pd->return_oop());
|
||||
}
|
||||
|
||||
void CompiledMethod::cleanup_inline_caches(bool clean_all/*=false*/) {
|
||||
assert_locked_or_safepoint(CompiledIC_lock);
|
||||
|
||||
address CompiledMethod::oops_reloc_begin() const {
|
||||
// If the method is not entrant or zombie then a JMP is plastered over the
|
||||
// first few bytes. If an oop in the old code was there, that oop
|
||||
// should not get GC'd. Skip the first few bytes of oops on
|
||||
@ -237,41 +237,7 @@ void CompiledMethod::cleanup_inline_caches(bool clean_all/*=false*/) {
|
||||
// This shouldn't matter, since oops of non-entrant methods are never used.
|
||||
// In fact, why are we bothering to look at oops in a non-entrant method??
|
||||
}
|
||||
|
||||
// Find all calls in an nmethod and clear the ones that point to non-entrant,
|
||||
// zombie and unloaded nmethods.
|
||||
ResourceMark rm;
|
||||
RelocIterator iter(this, low_boundary);
|
||||
while(iter.next()) {
|
||||
switch(iter.type()) {
|
||||
case relocInfo::virtual_call_type:
|
||||
case relocInfo::opt_virtual_call_type: {
|
||||
CompiledIC *ic = CompiledIC_at(&iter);
|
||||
// Ok, to lookup references to zombies here
|
||||
CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
|
||||
if( cb != NULL && cb->is_compiled() ) {
|
||||
CompiledMethod* nm = cb->as_compiled_method();
|
||||
// Clean inline caches pointing to zombie, non-entrant and unloaded methods
|
||||
if (clean_all || !nm->is_in_use() || (nm->method()->code() != nm)) ic->set_to_clean(is_alive());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case relocInfo::static_call_type: {
|
||||
CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc());
|
||||
CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
|
||||
if( cb != NULL && cb->is_compiled() ) {
|
||||
CompiledMethod* cm = cb->as_compiled_method();
|
||||
// Clean inline caches pointing to zombie, non-entrant and unloaded methods
|
||||
if (clean_all || !cm->is_in_use() || (cm->method()->code() != cm)) {
|
||||
csc->set_to_clean();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return low_boundary;
|
||||
}
|
||||
|
||||
int CompiledMethod::verify_icholder_relocations() {
|
||||
@ -437,17 +403,15 @@ unsigned char CompiledMethod::unloading_clock() {
|
||||
return OrderAccess::load_acquire(&_unloading_clock);
|
||||
}
|
||||
|
||||
// Processing of oop references should have been sufficient to keep
|
||||
// all strong references alive. Any weak references should have been
|
||||
// cleared as well. Visit all the metadata and ensure that it's
|
||||
// really alive.
|
||||
void CompiledMethod::verify_metadata_loaders(address low_boundary) {
|
||||
|
||||
// static_stub_Relocations may have dangling references to
|
||||
// nmethods so trim them out here. Otherwise it looks like
|
||||
// compiled code is maintaining a link to dead metadata.
|
||||
void CompiledMethod::clean_ic_stubs() {
|
||||
#ifdef ASSERT
|
||||
RelocIterator iter(this, low_boundary);
|
||||
while (iter.next()) {
|
||||
// static_stub_Relocations may have dangling references to
|
||||
// Method*s so trim them out here. Otherwise it looks like
|
||||
// compiled code is maintaining a link to dead metadata.
|
||||
address low_boundary = oops_reloc_begin();
|
||||
RelocIterator iter(this, low_boundary);
|
||||
while (iter.next()) {
|
||||
address static_call_addr = NULL;
|
||||
if (iter.type() == relocInfo::opt_virtual_call_type) {
|
||||
CompiledIC* cic = CompiledIC_at(&iter);
|
||||
@ -470,8 +434,6 @@ void CompiledMethod::verify_metadata_loaders(address low_boundary) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check that the metadata embedded in the nmethod is alive
|
||||
metadata_do(check_class);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -479,67 +441,43 @@ void CompiledMethod::verify_metadata_loaders(address low_boundary) {
|
||||
// GC to unload an nmethod if it contains otherwise unreachable
|
||||
// oops.
|
||||
|
||||
void CompiledMethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) {
|
||||
void CompiledMethod::do_unloading(BoolObjectClosure* is_alive) {
|
||||
// Make sure the oop's ready to receive visitors
|
||||
assert(!is_zombie() && !is_unloaded(),
|
||||
"should not call follow on zombie or unloaded nmethod");
|
||||
|
||||
// If the method is not entrant then a JMP is plastered over the
|
||||
// first few bytes. If an oop in the old code was there, that oop
|
||||
// should not get GC'd. Skip the first few bytes of oops on
|
||||
// not-entrant methods.
|
||||
address low_boundary = verified_entry_point();
|
||||
if (is_not_entrant()) {
|
||||
low_boundary += NativeJump::instruction_size;
|
||||
// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
|
||||
// (See comment above.)
|
||||
}
|
||||
address low_boundary = oops_reloc_begin();
|
||||
|
||||
// Exception cache
|
||||
clean_exception_cache();
|
||||
|
||||
// If class unloading occurred we first iterate over all inline caches and
|
||||
// clear ICs where the cached oop is referring to an unloaded klass or method.
|
||||
// The remaining live cached oops will be traversed in the relocInfo::oop_type
|
||||
// iteration below.
|
||||
if (unloading_occurred) {
|
||||
RelocIterator iter(this, low_boundary);
|
||||
while(iter.next()) {
|
||||
if (iter.type() == relocInfo::virtual_call_type) {
|
||||
CompiledIC *ic = CompiledIC_at(&iter);
|
||||
clean_ic_if_metadata_is_dead(ic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_unloading_oops(low_boundary, is_alive, unloading_occurred)) {
|
||||
if (do_unloading_oops(low_boundary, is_alive)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (do_unloading_jvmci(unloading_occurred)) {
|
||||
if (do_unloading_jvmci()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ensure that all metadata is still alive
|
||||
verify_metadata_loaders(low_boundary);
|
||||
// Cleanup exception cache and inline caches happens
|
||||
// after all the unloaded methods are found.
|
||||
}
|
||||
|
||||
// Clean references to unloaded nmethods at addr from this one, which is not unloaded.
|
||||
template <class CompiledICorStaticCall>
|
||||
static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from) {
|
||||
static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from,
|
||||
bool parallel, bool clean_all) {
|
||||
// Ok, to lookup references to zombies here
|
||||
CodeBlob *cb = CodeCache::find_blob_unsafe(addr);
|
||||
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
|
||||
if (nm != NULL) {
|
||||
if (nm->unloading_clock() != CompiledMethod::global_unloading_clock()) {
|
||||
if (parallel && nm->unloading_clock() != CompiledMethod::global_unloading_clock()) {
|
||||
// The nmethod has not been processed yet.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clean inline caches pointing to both zombie and not_entrant methods
|
||||
if (!nm->is_in_use() || (nm->method()->code() != nm)) {
|
||||
ic->set_to_clean();
|
||||
if (clean_all || !nm->is_in_use() || (nm->method()->code() != nm)) {
|
||||
ic->set_to_clean(from->is_alive());
|
||||
assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string());
|
||||
}
|
||||
}
|
||||
@ -547,12 +485,14 @@ static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address add
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, CompiledMethod* from) {
|
||||
return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), from);
|
||||
static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, CompiledMethod* from,
|
||||
bool parallel, bool clean_all = false) {
|
||||
return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), from, parallel, clean_all);
|
||||
}
|
||||
|
||||
static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, CompiledMethod* from) {
|
||||
return clean_if_nmethod_is_unloaded(csc, csc->destination(), from);
|
||||
static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, CompiledMethod* from,
|
||||
bool parallel, bool clean_all = false) {
|
||||
return clean_if_nmethod_is_unloaded(csc, csc->destination(), from, parallel, clean_all);
|
||||
}
|
||||
|
||||
bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred) {
|
||||
@ -562,47 +502,79 @@ bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unl
|
||||
assert(!is_zombie() && !is_unloaded(),
|
||||
"should not call follow on zombie or unloaded nmethod");
|
||||
|
||||
// If the method is not entrant then a JMP is plastered over the
|
||||
// first few bytes. If an oop in the old code was there, that oop
|
||||
// should not get GC'd. Skip the first few bytes of oops on
|
||||
// not-entrant methods.
|
||||
address low_boundary = verified_entry_point();
|
||||
if (is_not_entrant()) {
|
||||
low_boundary += NativeJump::instruction_size;
|
||||
// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
|
||||
// (See comment above.)
|
||||
address low_boundary = oops_reloc_begin();
|
||||
|
||||
if (do_unloading_oops(low_boundary, is_alive)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exception cache
|
||||
clean_exception_cache();
|
||||
#if INCLUDE_JVMCI
|
||||
if (do_unloading_jvmci()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return unload_nmethod_caches(/*parallel*/true, unloading_occurred);
|
||||
}
|
||||
|
||||
// Cleans caches in nmethods that point to either classes that are unloaded
|
||||
// or nmethods that are unloaded.
|
||||
//
|
||||
// Can be called either in parallel by G1 currently or after all
|
||||
// nmethods are unloaded. Return postponed=true in the parallel case for
|
||||
// inline caches found that point to nmethods that are not yet visited during
|
||||
// the do_unloading walk.
|
||||
bool CompiledMethod::unload_nmethod_caches(bool parallel, bool unloading_occurred) {
|
||||
|
||||
// Exception cache only needs to be called if unloading occurred
|
||||
if (unloading_occurred) {
|
||||
clean_exception_cache();
|
||||
}
|
||||
|
||||
bool postponed = cleanup_inline_caches_impl(parallel, unloading_occurred, /*clean_all*/false);
|
||||
|
||||
// All static stubs need to be cleaned.
|
||||
clean_ic_stubs();
|
||||
|
||||
// Check that the metadata embedded in the nmethod is alive
|
||||
DEBUG_ONLY(metadata_do(check_class));
|
||||
|
||||
return postponed;
|
||||
}
|
||||
|
||||
// Called to clean up after class unloading for live nmethods and from the sweeper
|
||||
// for all methods.
|
||||
bool CompiledMethod::cleanup_inline_caches_impl(bool parallel, bool unloading_occurred, bool clean_all) {
|
||||
assert_locked_or_safepoint(CompiledIC_lock);
|
||||
bool postponed = false;
|
||||
|
||||
RelocIterator iter(this, low_boundary);
|
||||
// Find all calls in an nmethod and clear the ones that point to non-entrant,
|
||||
// zombie and unloaded nmethods.
|
||||
RelocIterator iter(this, oops_reloc_begin());
|
||||
while(iter.next()) {
|
||||
|
||||
switch (iter.type()) {
|
||||
|
||||
case relocInfo::virtual_call_type:
|
||||
if (unloading_occurred) {
|
||||
// If class unloading occurred we first iterate over all inline caches and
|
||||
// clear ICs where the cached oop is referring to an unloaded klass or method.
|
||||
// If class unloading occurred we first clear ICs where the cached metadata
|
||||
// is referring to an unloaded klass or method.
|
||||
clean_ic_if_metadata_is_dead(CompiledIC_at(&iter));
|
||||
}
|
||||
|
||||
postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this);
|
||||
postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, parallel, clean_all);
|
||||
break;
|
||||
|
||||
case relocInfo::opt_virtual_call_type:
|
||||
postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this);
|
||||
postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, parallel, clean_all);
|
||||
break;
|
||||
|
||||
case relocInfo::static_call_type:
|
||||
postponed |= clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this);
|
||||
postponed |= clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, parallel, clean_all);
|
||||
break;
|
||||
|
||||
case relocInfo::oop_type:
|
||||
// handled by do_unloading_oops below
|
||||
// handled by do_unloading_oops already
|
||||
break;
|
||||
|
||||
case relocInfo::metadata_type:
|
||||
@ -613,19 +585,6 @@ bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unl
|
||||
}
|
||||
}
|
||||
|
||||
if (do_unloading_oops(low_boundary, is_alive, unloading_occurred)) {
|
||||
return postponed;
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (do_unloading_jvmci(unloading_occurred)) {
|
||||
return postponed;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ensure that all metadata is still alive
|
||||
verify_metadata_loaders(low_boundary);
|
||||
|
||||
return postponed;
|
||||
}
|
||||
|
||||
@ -636,32 +595,21 @@ void CompiledMethod::do_unloading_parallel_postponed() {
|
||||
assert(!is_zombie(),
|
||||
"should not call follow on zombie nmethod");
|
||||
|
||||
// If the method is not entrant then a JMP is plastered over the
|
||||
// first few bytes. If an oop in the old code was there, that oop
|
||||
// should not get GC'd. Skip the first few bytes of oops on
|
||||
// not-entrant methods.
|
||||
address low_boundary = verified_entry_point();
|
||||
if (is_not_entrant()) {
|
||||
low_boundary += NativeJump::instruction_size;
|
||||
// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
|
||||
// (See comment above.)
|
||||
}
|
||||
|
||||
RelocIterator iter(this, low_boundary);
|
||||
RelocIterator iter(this, oops_reloc_begin());
|
||||
while(iter.next()) {
|
||||
|
||||
switch (iter.type()) {
|
||||
|
||||
case relocInfo::virtual_call_type:
|
||||
clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this);
|
||||
clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, true);
|
||||
break;
|
||||
|
||||
case relocInfo::opt_virtual_call_type:
|
||||
clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this);
|
||||
clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, true);
|
||||
break;
|
||||
|
||||
case relocInfo::static_call_type:
|
||||
clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this);
|
||||
clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@ -331,8 +331,19 @@ public:
|
||||
|
||||
static address get_deopt_original_pc(const frame* fr);
|
||||
|
||||
// Inline cache support
|
||||
void cleanup_inline_caches(bool clean_all = false);
|
||||
// GC unloading support
|
||||
// Cleans unloaded klasses and unloaded nmethods in inline caches
|
||||
bool unload_nmethod_caches(bool parallel, bool class_unloading_occurred);
|
||||
|
||||
// Inline cache support for class unloading and nmethod unloading
|
||||
private:
|
||||
bool cleanup_inline_caches_impl(bool parallel, bool unloading_occurred, bool clean_all);
|
||||
public:
|
||||
bool cleanup_inline_caches(bool clean_all = false) {
|
||||
// Serial version used by sweeper and whitebox test
|
||||
return cleanup_inline_caches_impl(false, false, clean_all);
|
||||
}
|
||||
|
||||
virtual void clear_inline_caches();
|
||||
void clear_ic_stubs();
|
||||
|
||||
@ -364,12 +375,15 @@ public:
|
||||
void set_unloading_next(CompiledMethod* next) { _unloading_next = next; }
|
||||
CompiledMethod* unloading_next() { return _unloading_next; }
|
||||
|
||||
protected:
|
||||
address oops_reloc_begin() const;
|
||||
private:
|
||||
void static clean_ic_if_metadata_is_dead(CompiledIC *ic);
|
||||
|
||||
// Check that all metadata is still alive
|
||||
void verify_metadata_loaders(address low_boundary);
|
||||
void clean_ic_stubs();
|
||||
|
||||
virtual void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
public:
|
||||
virtual void do_unloading(BoolObjectClosure* is_alive);
|
||||
// The parallel versions are used by G1.
|
||||
virtual bool do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
virtual void do_unloading_parallel_postponed();
|
||||
@ -381,9 +395,9 @@ public:
|
||||
unsigned char unloading_clock();
|
||||
|
||||
protected:
|
||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred) = 0;
|
||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive) = 0;
|
||||
#if INCLUDE_JVMCI
|
||||
virtual bool do_unloading_jvmci(bool unloading_occurred) = 0;
|
||||
virtual bool do_unloading_jvmci() = 0;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@ -946,21 +946,8 @@ void nmethod::fix_oop_relocations(address begin, address end, bool initialize_im
|
||||
void nmethod::verify_clean_inline_caches() {
|
||||
assert_locked_or_safepoint(CompiledIC_lock);
|
||||
|
||||
// If the method is not entrant or zombie then a JMP is plastered over the
|
||||
// first few bytes. If an oop in the old code was there, that oop
|
||||
// should not get GC'd. Skip the first few bytes of oops on
|
||||
// not-entrant methods.
|
||||
address low_boundary = verified_entry_point();
|
||||
if (!is_in_use()) {
|
||||
low_boundary += NativeJump::instruction_size;
|
||||
// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
|
||||
// This means that the low_boundary is going to be a little too high.
|
||||
// This shouldn't matter, since oops of non-entrant methods are never used.
|
||||
// In fact, why are we bothering to look at oops in a non-entrant method??
|
||||
}
|
||||
|
||||
ResourceMark rm;
|
||||
RelocIterator iter(this, low_boundary);
|
||||
RelocIterator iter(this, oops_reloc_begin());
|
||||
while(iter.next()) {
|
||||
switch(iter.type()) {
|
||||
case relocInfo::virtual_call_type:
|
||||
@ -1041,13 +1028,17 @@ void nmethod::make_unloaded(oop cause) {
|
||||
flush_dependencies(/*delete_immediately*/false);
|
||||
|
||||
// Break cycle between nmethod & method
|
||||
LogTarget(Trace, class, unload) lt;
|
||||
LogTarget(Trace, class, unload, nmethod) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
ls.print_cr("making nmethod " INTPTR_FORMAT
|
||||
" unloadable, Method*(" INTPTR_FORMAT
|
||||
"), cause(" INTPTR_FORMAT ")",
|
||||
p2i(this), p2i(_method), p2i(cause));
|
||||
ls.print("making nmethod " INTPTR_FORMAT
|
||||
" unloadable, Method*(" INTPTR_FORMAT
|
||||
"), cause(" INTPTR_FORMAT ") ",
|
||||
p2i(this), p2i(_method), p2i(cause));
|
||||
if (cause != NULL) {
|
||||
cause->print_value_on(&ls);
|
||||
}
|
||||
ls.cr();
|
||||
}
|
||||
// Unlink the osr method, so we do not look this up again
|
||||
if (is_osr_method()) {
|
||||
@ -1378,17 +1369,15 @@ void nmethod::flush_dependencies(bool delete_immediately) {
|
||||
|
||||
|
||||
// If this oop is not live, the nmethod can be unloaded.
|
||||
bool nmethod::can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred) {
|
||||
bool nmethod::can_unload(BoolObjectClosure* is_alive, oop* root) {
|
||||
assert(root != NULL, "just checking");
|
||||
oop obj = *root;
|
||||
if (obj == NULL || is_alive->do_object_b(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If ScavengeRootsInCode is true, an nmethod might be unloaded
|
||||
// simply because one of its constant oops has gone dead.
|
||||
// An nmethod might be unloaded simply because one of its constant oops has gone dead.
|
||||
// No actual classes need to be unloaded in order for this to occur.
|
||||
assert(unloading_occurred || ScavengeRootsInCode, "Inconsistency in unloading");
|
||||
make_unloaded(obj);
|
||||
return true;
|
||||
}
|
||||
@ -1466,7 +1455,7 @@ void nmethod::post_compiled_method_unload() {
|
||||
set_unload_reported();
|
||||
}
|
||||
|
||||
bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *is_alive, bool unloading_occurred) {
|
||||
bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *is_alive) {
|
||||
assert(iter_at_oop->type() == relocInfo::oop_type, "Wrong relocation type");
|
||||
|
||||
oop_Relocation* r = iter_at_oop->oop_reloc();
|
||||
@ -1477,7 +1466,7 @@ bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *i
|
||||
"oop must be found in exactly one place");
|
||||
if (r->oop_is_immediate() && r->oop_value() != NULL) {
|
||||
// Unload this nmethod if the oop is dead.
|
||||
if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) {
|
||||
if (can_unload(is_alive, r->oop_addr())) {
|
||||
return true;;
|
||||
}
|
||||
}
|
||||
@ -1485,18 +1474,18 @@ bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *i
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nmethod::do_unloading_scopes(BoolObjectClosure* is_alive, bool unloading_occurred) {
|
||||
bool nmethod::do_unloading_scopes(BoolObjectClosure* is_alive) {
|
||||
// Scopes
|
||||
for (oop* p = oops_begin(); p < oops_end(); p++) {
|
||||
if (*p == Universe::non_oop_word()) continue; // skip non-oops
|
||||
if (can_unload(is_alive, p, unloading_occurred)) {
|
||||
if (can_unload(is_alive, p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nmethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred) {
|
||||
bool nmethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive) {
|
||||
// Compiled code
|
||||
|
||||
// Prevent extra code cache walk for platforms that don't have immediate oops.
|
||||
@ -1504,18 +1493,18 @@ bool nmethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_aliv
|
||||
RelocIterator iter(this, low_boundary);
|
||||
while (iter.next()) {
|
||||
if (iter.type() == relocInfo::oop_type) {
|
||||
if (unload_if_dead_at(&iter, is_alive, unloading_occurred)) {
|
||||
if (unload_if_dead_at(&iter, is_alive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return do_unloading_scopes(is_alive, unloading_occurred);
|
||||
return do_unloading_scopes(is_alive);
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
bool nmethod::do_unloading_jvmci(bool unloading_occurred) {
|
||||
bool nmethod::do_unloading_jvmci() {
|
||||
if (_jvmci_installed_code != NULL) {
|
||||
if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) {
|
||||
if (_jvmci_installed_code_triggers_unloading) {
|
||||
@ -1533,15 +1522,9 @@ bool nmethod::do_unloading_jvmci(bool unloading_occurred) {
|
||||
|
||||
// Iterate over metadata calling this function. Used by RedefineClasses
|
||||
void nmethod::metadata_do(void f(Metadata*)) {
|
||||
address low_boundary = verified_entry_point();
|
||||
if (is_not_entrant()) {
|
||||
low_boundary += NativeJump::instruction_size;
|
||||
// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
|
||||
// (See comment above.)
|
||||
}
|
||||
{
|
||||
// Visit all immediate references that are embedded in the instruction stream.
|
||||
RelocIterator iter(this, low_boundary);
|
||||
RelocIterator iter(this, oops_reloc_begin());
|
||||
while (iter.next()) {
|
||||
if (iter.type() == relocInfo::metadata_type ) {
|
||||
metadata_Relocation* r = iter.metadata_reloc();
|
||||
@ -1588,20 +1571,9 @@ void nmethod::oops_do(OopClosure* f, bool allow_zombie) {
|
||||
assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod");
|
||||
assert(!is_unloaded(), "should not call follow on unloaded nmethod");
|
||||
|
||||
// If the method is not entrant or zombie then a JMP is plastered over the
|
||||
// first few bytes. If an oop in the old code was there, that oop
|
||||
// should not get GC'd. Skip the first few bytes of oops on
|
||||
// not-entrant methods.
|
||||
address low_boundary = verified_entry_point();
|
||||
if (is_not_entrant()) {
|
||||
low_boundary += NativeJump::instruction_size;
|
||||
// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
|
||||
// (See comment above.)
|
||||
}
|
||||
|
||||
// Prevent extra code cache walk for platforms that don't have immediate oops.
|
||||
if (relocInfo::mustIterateImmediateOopsInCode()) {
|
||||
RelocIterator iter(this, low_boundary);
|
||||
RelocIterator iter(this, oops_reloc_begin());
|
||||
|
||||
while (iter.next()) {
|
||||
if (iter.type() == relocInfo::oop_type ) {
|
||||
@ -1650,7 +1622,11 @@ bool nmethod::test_set_oops_do_mark() {
|
||||
break;
|
||||
}
|
||||
// Mark was clear when we first saw this guy.
|
||||
if (TraceScavenge) { print_on(tty, "oops_do, mark"); }
|
||||
LogTarget(Trace, gc, nmethod) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
CompileTask::print(&ls, this, "oops_do, mark", /*short_form:*/ true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1659,7 +1635,7 @@ bool nmethod::test_set_oops_do_mark() {
|
||||
}
|
||||
|
||||
void nmethod::oops_do_marking_prologue() {
|
||||
if (TraceScavenge) { tty->print_cr("[oops_do_marking_prologue"); }
|
||||
log_trace(gc, nmethod)("oops_do_marking_prologue");
|
||||
assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
|
||||
// We use cmpxchg instead of regular assignment here because the user
|
||||
// may fork a bunch of threads, and we need them all to see the same state.
|
||||
@ -1675,20 +1651,26 @@ void nmethod::oops_do_marking_epilogue() {
|
||||
nmethod* next = cur->_oops_do_mark_link;
|
||||
cur->_oops_do_mark_link = NULL;
|
||||
DEBUG_ONLY(cur->verify_oop_relocations());
|
||||
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
|
||||
|
||||
LogTarget(Trace, gc, nmethod) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
CompileTask::print(&ls, cur, "oops_do, unmark", /*short_form:*/ true);
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
nmethod* required = _oops_do_mark_nmethods;
|
||||
nmethod* observed = Atomic::cmpxchg((nmethod*)NULL, &_oops_do_mark_nmethods, required);
|
||||
guarantee(observed == required, "no races in this sequential code");
|
||||
if (TraceScavenge) { tty->print_cr("oops_do_marking_epilogue]"); }
|
||||
log_trace(gc, nmethod)("oops_do_marking_epilogue");
|
||||
}
|
||||
|
||||
class DetectScavengeRoot: public OopClosure {
|
||||
bool _detected_scavenge_root;
|
||||
nmethod* _print_nm;
|
||||
public:
|
||||
DetectScavengeRoot() : _detected_scavenge_root(false)
|
||||
{ NOT_PRODUCT(_print_nm = NULL); }
|
||||
DetectScavengeRoot(nmethod* nm) : _detected_scavenge_root(false), _print_nm(nm) {}
|
||||
|
||||
bool detected_scavenge_root() { return _detected_scavenge_root; }
|
||||
virtual void do_oop(oop* p) {
|
||||
if ((*p) != NULL && Universe::heap()->is_scavengable(*p)) {
|
||||
@ -1699,21 +1681,25 @@ public:
|
||||
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
|
||||
|
||||
#ifndef PRODUCT
|
||||
nmethod* _print_nm;
|
||||
void maybe_print(oop* p) {
|
||||
if (_print_nm == NULL) return;
|
||||
if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root");
|
||||
tty->print_cr("" PTR_FORMAT "[offset=%d] detected scavengable oop " PTR_FORMAT " (found at " PTR_FORMAT ")",
|
||||
p2i(_print_nm), (int)((intptr_t)p - (intptr_t)_print_nm),
|
||||
p2i(*p), p2i(p));
|
||||
(*p)->print();
|
||||
LogTarget(Trace, gc, nmethod) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
if (!_detected_scavenge_root) {
|
||||
CompileTask::print(&ls, _print_nm, "new scavenge root", /*short_form:*/ true);
|
||||
}
|
||||
ls.print("" PTR_FORMAT "[offset=%d] detected scavengable oop " PTR_FORMAT " (found at " PTR_FORMAT ") ",
|
||||
p2i(_print_nm), (int)((intptr_t)p - (intptr_t)_print_nm),
|
||||
p2i(*p), p2i(p));
|
||||
(*p)->print_value_on(&ls);
|
||||
ls.cr();
|
||||
}
|
||||
}
|
||||
#endif //PRODUCT
|
||||
};
|
||||
|
||||
bool nmethod::detect_scavenge_root_oops() {
|
||||
DetectScavengeRoot detect_scavenge_root;
|
||||
NOT_PRODUCT(if (TraceScavenge) detect_scavenge_root._print_nm = this);
|
||||
DetectScavengeRoot detect_scavenge_root(this);
|
||||
oops_do(&detect_scavenge_root);
|
||||
return detect_scavenge_root.detected_scavenge_root();
|
||||
}
|
||||
|
||||
@ -484,18 +484,18 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive);
|
||||
#if INCLUDE_JVMCI
|
||||
// See comment for _jvmci_installed_code_triggers_unloading field.
|
||||
// Returns whether this nmethod was unloaded.
|
||||
virtual bool do_unloading_jvmci(bool unloading_occurred);
|
||||
virtual bool do_unloading_jvmci();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool do_unloading_scopes(BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
bool do_unloading_scopes(BoolObjectClosure* is_alive);
|
||||
// Unload a nmethod if the *root object is dead.
|
||||
bool can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred);
|
||||
bool unload_if_dead_at(RelocIterator *iter_at_oop, BoolObjectClosure* is_alive, bool unloading_occurred);
|
||||
bool can_unload(BoolObjectClosure* is_alive, oop* root);
|
||||
bool unload_if_dead_at(RelocIterator *iter_at_oop, BoolObjectClosure* is_alive);
|
||||
|
||||
public:
|
||||
void oops_do(OopClosure* f) { oops_do(f, false); }
|
||||
|
||||
@ -3355,7 +3355,7 @@ private:
|
||||
add_to_postponed_list(nm);
|
||||
}
|
||||
|
||||
// Mark that this thread has been cleaned/unloaded.
|
||||
// Mark that this nmethod has been cleaned/unloaded.
|
||||
// After this call, it will be safe to ask if this nmethod was unloaded or not.
|
||||
nm->set_unloading_clock(CompiledMethod::global_unloading_clock());
|
||||
}
|
||||
|
||||
@ -365,20 +365,32 @@ void CollectedHeap::check_for_valid_allocation_state() {
|
||||
}
|
||||
#endif
|
||||
|
||||
HeapWord* CollectedHeap::allocate_from_tlab_slow(Klass* klass, Thread* thread, size_t size) {
|
||||
HeapWord* CollectedHeap::obj_allocate_raw(Klass* klass, size_t size,
|
||||
bool* gc_overhead_limit_was_exceeded, TRAPS) {
|
||||
if (UseTLAB) {
|
||||
HeapWord* result = allocate_from_tlab(klass, size, THREAD);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return Universe::heap()->mem_allocate(size, gc_overhead_limit_was_exceeded);
|
||||
}
|
||||
|
||||
HeapWord* CollectedHeap::allocate_from_tlab_slow(Klass* klass, size_t size, TRAPS) {
|
||||
ThreadLocalAllocBuffer& tlab = THREAD->tlab();
|
||||
|
||||
// Retain tlab and allocate object in shared space if
|
||||
// the amount free in the tlab is too large to discard.
|
||||
if (thread->tlab().free() > thread->tlab().refill_waste_limit()) {
|
||||
thread->tlab().record_slow_allocation(size);
|
||||
if (tlab.free() > tlab.refill_waste_limit()) {
|
||||
tlab.record_slow_allocation(size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Discard tlab and allocate a new one.
|
||||
// To minimize fragmentation, the last TLAB may be smaller than the rest.
|
||||
size_t new_tlab_size = thread->tlab().compute_size(size);
|
||||
size_t new_tlab_size = tlab.compute_size(size);
|
||||
|
||||
thread->tlab().clear_before_allocation();
|
||||
tlab.clear_before_allocation();
|
||||
|
||||
if (new_tlab_size == 0) {
|
||||
return NULL;
|
||||
@ -397,7 +409,7 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(Klass* klass, Thread* thread, s
|
||||
assert(actual_tlab_size != 0, "Allocation succeeded but actual size not updated. obj at: " PTR_FORMAT " min: " SIZE_FORMAT ", desired: " SIZE_FORMAT,
|
||||
p2i(obj), min_tlab_size, new_tlab_size);
|
||||
|
||||
AllocTracer::send_allocation_in_new_tlab(klass, obj, actual_tlab_size * HeapWordSize, size * HeapWordSize, thread);
|
||||
AllocTracer::send_allocation_in_new_tlab(klass, obj, actual_tlab_size * HeapWordSize, size * HeapWordSize, THREAD);
|
||||
|
||||
if (ZeroTLAB) {
|
||||
// ..and clear it.
|
||||
@ -412,7 +424,7 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(Klass* klass, Thread* thread, s
|
||||
Copy::fill_to_words(obj + hdr_size, actual_tlab_size - hdr_size, badHeapWordVal);
|
||||
#endif // ASSERT
|
||||
}
|
||||
thread->tlab().fill(obj, obj + size, actual_tlab_size);
|
||||
tlab.fill(obj, obj + size, actual_tlab_size);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@ -141,8 +141,15 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
virtual void resize_all_tlabs();
|
||||
|
||||
// Allocate from the current thread's TLAB, with broken-out slow path.
|
||||
inline static HeapWord* allocate_from_tlab(Klass* klass, Thread* thread, size_t size);
|
||||
static HeapWord* allocate_from_tlab_slow(Klass* klass, Thread* thread, size_t size);
|
||||
inline static HeapWord* allocate_from_tlab(Klass* klass, size_t size, TRAPS);
|
||||
static HeapWord* allocate_from_tlab_slow(Klass* klass, size_t size, TRAPS);
|
||||
|
||||
// Raw memory allocation facilities
|
||||
// The obj and array allocate methods are covers for these methods.
|
||||
// mem_allocate() should never be
|
||||
// called to allocate TLABs, only individual objects.
|
||||
virtual HeapWord* mem_allocate(size_t size,
|
||||
bool* gc_overhead_limit_was_exceeded) = 0;
|
||||
|
||||
// Allocate an uninitialized block of the given size, or returns NULL if
|
||||
// this is impossible.
|
||||
@ -309,12 +316,12 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
inline static oop array_allocate_nozero(Klass* klass, int size, int length, TRAPS);
|
||||
inline static oop class_allocate(Klass* klass, int size, TRAPS);
|
||||
|
||||
// Raw memory allocation facilities
|
||||
// The obj and array allocate methods are covers for these methods.
|
||||
// mem_allocate() should never be
|
||||
// called to allocate TLABs, only individual objects.
|
||||
virtual HeapWord* mem_allocate(size_t size,
|
||||
bool* gc_overhead_limit_was_exceeded) = 0;
|
||||
// Raw memory allocation. This may or may not use TLAB allocations to satisfy the
|
||||
// allocation. A GC implementation may override this function to satisfy the allocation
|
||||
// in any way. But the default is to try a TLAB allocation, and otherwise perform
|
||||
// mem_allocate.
|
||||
virtual HeapWord* obj_allocate_raw(Klass* klass, size_t size,
|
||||
bool* gc_overhead_limit_was_exceeded, TRAPS);
|
||||
|
||||
// Utilities for turning raw memory into filler objects.
|
||||
//
|
||||
|
||||
@ -137,18 +137,10 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(Klass* klass, size_t size, T
|
||||
return NULL; // caller does a CHECK_0 too
|
||||
}
|
||||
|
||||
HeapWord* result = NULL;
|
||||
if (UseTLAB) {
|
||||
result = allocate_from_tlab(klass, THREAD, size);
|
||||
if (result != NULL) {
|
||||
assert(!HAS_PENDING_EXCEPTION,
|
||||
"Unexpected exception, will result in uninitialized storage");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
bool gc_overhead_limit_was_exceeded = false;
|
||||
result = Universe::heap()->mem_allocate(size,
|
||||
&gc_overhead_limit_was_exceeded);
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
HeapWord* result = heap->obj_allocate_raw(klass, size, &gc_overhead_limit_was_exceeded, THREAD);
|
||||
|
||||
if (result != NULL) {
|
||||
NOT_PRODUCT(Universe::heap()->
|
||||
check_for_non_bad_heap_word_value(result, size));
|
||||
@ -161,7 +153,6 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(Klass* klass, size_t size, T
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
if (!gc_overhead_limit_was_exceeded) {
|
||||
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
|
||||
report_java_out_of_memory("Java heap space");
|
||||
@ -193,15 +184,18 @@ HeapWord* CollectedHeap::common_mem_allocate_init(Klass* klass, size_t size, TRA
|
||||
return obj;
|
||||
}
|
||||
|
||||
HeapWord* CollectedHeap::allocate_from_tlab(Klass* klass, Thread* thread, size_t size) {
|
||||
HeapWord* CollectedHeap::allocate_from_tlab(Klass* klass, size_t size, TRAPS) {
|
||||
assert(UseTLAB, "should use UseTLAB");
|
||||
|
||||
HeapWord* obj = thread->tlab().allocate(size);
|
||||
HeapWord* obj = THREAD->tlab().allocate(size);
|
||||
if (obj != NULL) {
|
||||
return obj;
|
||||
}
|
||||
// Otherwise...
|
||||
return allocate_from_tlab_slow(klass, thread, size);
|
||||
obj = allocate_from_tlab_slow(klass, size, THREAD);
|
||||
assert(obj == NULL || !HAS_PENDING_EXCEPTION,
|
||||
"Unexpected exception, will result in uninitialized storage");
|
||||
return obj;
|
||||
}
|
||||
|
||||
void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
|
||||
|
||||
@ -449,12 +449,6 @@ bool Method::init_method_counters(MethodCounters* counters) {
|
||||
return Atomic::replace_if_null(counters, &_method_counters);
|
||||
}
|
||||
|
||||
void Method::cleanup_inline_caches() {
|
||||
// The current system doesn't use inline caches in the interpreter
|
||||
// => nothing to do (keep this method around for future use)
|
||||
}
|
||||
|
||||
|
||||
int Method::extra_stack_words() {
|
||||
// not an inline function, to avoid a header dependency on Interpreter
|
||||
return extra_stack_entries() * Interpreter::stackElementSize;
|
||||
|
||||
@ -904,9 +904,6 @@ class Method : public Metadata {
|
||||
return method_holder()->lookup_osr_nmethod(this, bci, level, match_level);
|
||||
}
|
||||
|
||||
// Inline cache support
|
||||
void cleanup_inline_caches();
|
||||
|
||||
// Find if klass for method is loaded
|
||||
bool is_klass_loaded_by_klass_index(int klass_index) const;
|
||||
bool is_klass_loaded(int refinfo_index, bool must_be_resolved = false) const;
|
||||
|
||||
@ -553,6 +553,7 @@ static SpecialFlag const special_jvm_flags[] = {
|
||||
{ "CheckEndorsedAndExtDirs", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "DeferThrSuspendLoopCount", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "DeferPollingPageLoopCount", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "TraceScavenge", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "PermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() },
|
||||
{ "MaxPermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() },
|
||||
{ "SharedReadWriteSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
|
||||
|
||||
@ -1055,9 +1055,6 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||
develop(bool, TraceFinalizerRegistration, false, \
|
||||
"Trace registration of final references") \
|
||||
\
|
||||
notproduct(bool, TraceScavenge, false, \
|
||||
"Trace scavenge") \
|
||||
\
|
||||
product(bool, IgnoreEmptyClassPaths, false, \
|
||||
"Ignore empty path elements in -classpath") \
|
||||
\
|
||||
|
||||
@ -204,13 +204,6 @@ void VM_Verify::doit() {
|
||||
}
|
||||
|
||||
bool VM_PrintThreads::doit_prologue() {
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
JavaThread* jt = JavaThread::current();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
|
||||
if (jt->has_pending_exception()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Heap_lock if concurrent locks will be dumped
|
||||
if (_print_concurrent_locks) {
|
||||
Heap_lock->lock();
|
||||
@ -248,19 +241,6 @@ VM_FindDeadlocks::~VM_FindDeadlocks() {
|
||||
}
|
||||
}
|
||||
|
||||
bool VM_FindDeadlocks::doit_prologue() {
|
||||
if (_concurrent_locks) {
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
JavaThread* jt = JavaThread::current();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
|
||||
if (jt->has_pending_exception()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VM_FindDeadlocks::doit() {
|
||||
// Update the hazard ptr in the originating thread to the current
|
||||
// list of threads. This VM operation needs the current list of
|
||||
@ -316,13 +296,6 @@ VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result,
|
||||
}
|
||||
|
||||
bool VM_ThreadDump::doit_prologue() {
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
JavaThread* jt = JavaThread::current();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
|
||||
if (jt->has_pending_exception()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_with_locked_synchronizers) {
|
||||
// Acquire Heap_lock to dump concurrent locks
|
||||
Heap_lock->lock();
|
||||
|
||||
@ -421,7 +421,6 @@ class VM_FindDeadlocks: public VM_Operation {
|
||||
DeadlockCycle* result() { return _deadlocks; };
|
||||
VMOp_Type type() const { return VMOp_FindDeadlocks; }
|
||||
void doit();
|
||||
bool doit_prologue();
|
||||
};
|
||||
|
||||
class ThreadDumpResult;
|
||||
|
||||
@ -1081,9 +1081,6 @@ JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jo
|
||||
"The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
|
||||
}
|
||||
|
||||
// make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
|
||||
|
||||
// Must use ThreadDumpResult to store the ThreadSnapshot.
|
||||
// GC may occur after the thread snapshots are taken but before
|
||||
// this function returns. The threadObj and other oops kept
|
||||
@ -1154,9 +1151,6 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
|
||||
jboolean locked_synchronizers, jint maxDepth))
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
// make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
|
||||
|
||||
typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
|
||||
int num_threads = (ta != NULL ? ta->length() : 0);
|
||||
typeArrayHandle ids_ah(THREAD, ta);
|
||||
|
||||
@ -369,7 +369,7 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list,
|
||||
}
|
||||
} else {
|
||||
if (concurrent_locks) {
|
||||
if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
|
||||
if (waitingToLockBlocker->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
|
||||
oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
|
||||
// This JavaThread (if there is one) is protected by the
|
||||
// ThreadsListSetter in VM_FindDeadlocks::doit().
|
||||
@ -678,8 +678,8 @@ void ConcurrentLocksDump::dump_at_safepoint() {
|
||||
GrowableArray<oop>* aos_objects = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true /* C_heap */);
|
||||
|
||||
// Find all instances of AbstractOwnableSynchronizer
|
||||
HeapInspection::find_instances_at_safepoint(SystemDictionary::abstract_ownable_synchronizer_klass(),
|
||||
aos_objects);
|
||||
HeapInspection::find_instances_at_safepoint(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass(),
|
||||
aos_objects);
|
||||
// Build a map of thread to its owned AQS locks
|
||||
build_map(aos_objects);
|
||||
|
||||
@ -832,7 +832,7 @@ ThreadSnapshot::ThreadSnapshot(ThreadsList * t_list, JavaThread* thread) {
|
||||
_thread_status == java_lang_Thread::PARKED_TIMED)) {
|
||||
|
||||
_blocker_object = thread->current_park_blocker();
|
||||
if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
|
||||
if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
|
||||
_blocker_object_owner = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(_blocker_object);
|
||||
}
|
||||
}
|
||||
@ -923,7 +923,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
|
||||
st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
|
||||
p2i(waitingToLockBlocker),
|
||||
waitingToLockBlocker->klass()->external_name());
|
||||
assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
|
||||
assert(waitingToLockBlocker->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass()),
|
||||
"Must be an AbstractOwnableSynchronizer");
|
||||
oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
|
||||
currentThread = java_lang_Thread::thread(ownerObj);
|
||||
|
||||
@ -109,10 +109,6 @@ class SocketOutputStream extends FileOutputStream {
|
||||
try {
|
||||
socketWrite0(fd, b, off, len);
|
||||
} catch (SocketException se) {
|
||||
if (se instanceof sun.net.ConnectionResetException) {
|
||||
impl.setConnectionReset();
|
||||
se = new SocketException("Connection reset");
|
||||
}
|
||||
if (impl.isClosedOrPending()) {
|
||||
throw new SocketException("Socket closed");
|
||||
} else {
|
||||
|
||||
@ -377,7 +377,8 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
int len;
|
||||
while ((len = is.readLine(lbuf)) != -1) {
|
||||
boolean lineContinued = false;
|
||||
if (lbuf[--len] != '\n') {
|
||||
byte c = lbuf[--len];
|
||||
if (c != '\n' && c != '\r') {
|
||||
throw new IOException("line too long");
|
||||
}
|
||||
if (len > 0 && lbuf[len-1] == '\r') {
|
||||
|
||||
@ -205,7 +205,8 @@ public class Manifest implements Cloneable {
|
||||
byte[] lastline = null;
|
||||
|
||||
while ((len = fis.readLine(lbuf)) != -1) {
|
||||
if (lbuf[--len] != '\n') {
|
||||
byte c = lbuf[--len];
|
||||
if (c != '\n' && c != '\r') {
|
||||
throw new IOException("manifest line too long");
|
||||
}
|
||||
if (len > 0 && lbuf[len-1] == '\r') {
|
||||
@ -381,13 +382,18 @@ public class Manifest implements Cloneable {
|
||||
}
|
||||
int tpos = pos;
|
||||
int maxpos = tpos + n;
|
||||
while (tpos < maxpos && tbuf[tpos++] != '\n') ;
|
||||
byte c = 0;
|
||||
// jar.spec.newline: CRLF | LF | CR (not followed by LF)
|
||||
while (tpos < maxpos && (c = tbuf[tpos++]) != '\n' && c != '\r');
|
||||
if (c == '\r' && tpos < maxpos && tbuf[tpos] == '\n') {
|
||||
tpos++;
|
||||
}
|
||||
n = tpos - pos;
|
||||
System.arraycopy(tbuf, pos, b, off, n);
|
||||
off += n;
|
||||
total += n;
|
||||
pos = tpos;
|
||||
if (tbuf[tpos-1] == '\n') {
|
||||
if (c == '\n' || c == '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -178,6 +178,7 @@ MMK=MMK
|
||||
MNT=MNT
|
||||
MOP=MOP
|
||||
MRO=MRO
|
||||
MRU=MRU
|
||||
MTL=MTL
|
||||
MUR=MUR
|
||||
MVR=MVR
|
||||
@ -399,6 +400,7 @@ mmk=Myanma Kyat
|
||||
mnt=Mongolian Tugrik
|
||||
mop=Macanese Pataca
|
||||
mro=Mauritanian Ouguiya
|
||||
mru=Mauritanian Ouguiya
|
||||
mtl=Maltese Lira
|
||||
mur=Mauritian Rupee
|
||||
mvr=Maldivian Rufiyaa
|
||||
|
||||
@ -108,13 +108,8 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
|
||||
loff += n;
|
||||
continue;
|
||||
}
|
||||
if (errno == ECONNRESET) {
|
||||
JNU_ThrowByName(env, "sun/net/ConnectionResetException",
|
||||
"Connection reset");
|
||||
} else {
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
(env, "java/net/SocketException", "Write failed");
|
||||
}
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
(env, "java/net/SocketException", "Write failed");
|
||||
if (bufP != BUF) {
|
||||
free(bufP);
|
||||
}
|
||||
|
||||
@ -452,8 +452,12 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
* packages is more than one. Sets {@link #createoverview} field to true.
|
||||
*/
|
||||
protected void setCreateOverview() {
|
||||
if ((overviewpath != null || packages.size() > 1) && !nooverview) {
|
||||
createoverview = true;
|
||||
if (!nooverview) {
|
||||
if (overviewpath != null
|
||||
|| modules.size() > 1
|
||||
|| (modules.isEmpty() && packages.size() > 1)) {
|
||||
createoverview = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -884,7 +884,7 @@ table.striped {
|
||||
border: 1px solid black;
|
||||
}
|
||||
table.striped > thead {
|
||||
background-color: #DDD;
|
||||
background-color: #E3E3E3;
|
||||
}
|
||||
table.striped > thead > tr > th, table.striped > thead > tr > td {
|
||||
border: 1px solid black;
|
||||
|
||||
140
test/jdk/java/net/Socket/ReadAfterReset.java
Normal file
140
test/jdk/java/net/Socket/ReadAfterReset.java
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @requires (os.family == "linux" | os.family == "mac")
|
||||
* @bug 8203937
|
||||
* @summary Test reading bytes from a socket after the connection has been
|
||||
* reset by the peer
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* This test exercises platform specific and unspecified behavior. It exists
|
||||
* only to ensure that the behavior doesn't change between JDK releases.
|
||||
*/
|
||||
|
||||
public class ReadAfterReset {
|
||||
private static final PrintStream out = System.out;
|
||||
|
||||
// number of bytes to write before the connection reset
|
||||
private static final int NUM_BYTES_TO_WRITE = 1000;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
try (ServerSocket ss = new ServerSocket()) {
|
||||
ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
|
||||
/**
|
||||
* Connect to the server which will write some bytes and reset the
|
||||
* connection. The client then attempts to read the bytes sent by
|
||||
* the server before it closed the connection.
|
||||
*/
|
||||
out.println("Test connection ...");
|
||||
try (Socket s = new Socket()) {
|
||||
s.connect(ss.getLocalSocketAddress());
|
||||
int nwrote = acceptAndResetConnection(ss);
|
||||
int nread = readUntilIOException(s);
|
||||
if (nread != nwrote) {
|
||||
throw new RuntimeException("Client read " + nread + ", expected " + nwrote);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the server which will write some bytes and reset the
|
||||
* connection. The client then writes to its end of the connection,
|
||||
* failing as the connection is reset. It then attempts to read the
|
||||
* bytes sent by the server before it closed the connection.
|
||||
*/
|
||||
out.println();
|
||||
out.println("Test connection ...");
|
||||
try (Socket s = new Socket()) {
|
||||
s.connect(ss.getLocalSocketAddress());
|
||||
int nwrote = acceptAndResetConnection(ss);
|
||||
writeUntilIOException(s);
|
||||
int nread = readUntilIOException(s);
|
||||
if (nread != nwrote) {
|
||||
throw new RuntimeException("Client read " + nread + ", expected " + nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a connection, write bytes, and then reset the connection
|
||||
*/
|
||||
static int acceptAndResetConnection(ServerSocket ss) throws IOException {
|
||||
int count = NUM_BYTES_TO_WRITE;
|
||||
try (Socket peer = ss.accept()) {
|
||||
peer.getOutputStream().write(new byte[count]);
|
||||
peer.setSoLinger(true, 0);
|
||||
out.format("Server wrote %d bytes and reset connection%n", count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write bytes to a socket until I/O exception is thrown
|
||||
*/
|
||||
static void writeUntilIOException(Socket s) {
|
||||
try {
|
||||
byte[] bytes = new byte[100];
|
||||
while (true) {
|
||||
s.getOutputStream().write(bytes);
|
||||
out.format("Client wrote %d bytes%n", bytes.length);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
out.format("Client write failed: %s (expected)%n", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes from a socket until I/O exception is thrown.
|
||||
*
|
||||
* @return the number of bytes read before the I/O exception was thrown
|
||||
*/
|
||||
static int readUntilIOException(Socket s) {
|
||||
int nread = 0;
|
||||
try {
|
||||
byte[] bytes = new byte[100];
|
||||
while (true) {
|
||||
int n = s.getInputStream().read(bytes);
|
||||
if (n < 0) {
|
||||
out.println("Client read EOF");
|
||||
break;
|
||||
} else {
|
||||
out.format("Client read %s bytes%n", n);
|
||||
nread += n;
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
out.format("Client read failed: %s (expected)%n", ioe);
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759
|
||||
* 8039317 8074350 8074351 8145952 8187946
|
||||
* 8039317 8074350 8074351 8145952 8187946 8193552 8202026 8204269
|
||||
* @summary Validate ISO 4217 data for Currency class.
|
||||
* @modules java.base/java.util:open
|
||||
* jdk.localedata
|
||||
@ -96,7 +96,7 @@ public class ValidateISO4217 {
|
||||
/* Codes that are obsolete, do not have related country */
|
||||
static final String otherCodes =
|
||||
"ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
|
||||
+ "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-MZM-NLG-"
|
||||
+ "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"
|
||||
+ "PTE-ROL-RUR-SDD-SIT-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-"
|
||||
+ "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"
|
||||
+ "YUM-ZMK-ZWD-ZWN-ZWR";
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#
|
||||
#
|
||||
# Amendments up until ISO 4217 AMENDMENT NUMBER 164
|
||||
# (As of 22 September 2017)
|
||||
# Amendments up until ISO 4217 AMENDMENT NUMBER 167
|
||||
# (As of 4 June 2018)
|
||||
#
|
||||
|
||||
# Version
|
||||
FILEVERSION=3
|
||||
DATAVERSION=164
|
||||
DATAVERSION=167
|
||||
|
||||
# ISO 4217 currency data
|
||||
AF AFN 971 2
|
||||
@ -135,14 +135,14 @@ KR KRW 410 0
|
||||
KW KWD 414 3
|
||||
KG KGS 417 2
|
||||
LA LAK 418 2
|
||||
LV LVL 428 2 2013-12-31-22-00-00 EUR 978 2
|
||||
LV EUR 978 2
|
||||
LB LBP 422 2
|
||||
#LS ZAR 710 2
|
||||
LS LSL 426 2
|
||||
LR LRD 430 2
|
||||
LY LYD 434 3
|
||||
LI CHF 756 2
|
||||
LT LTL 440 2 2014-12-31-22-00-00 EUR 978 2
|
||||
LT EUR 978 2
|
||||
LU EUR 978 2
|
||||
MO MOP 446 2
|
||||
MK MKD 807 2
|
||||
@ -154,7 +154,7 @@ ML XOF 952 0
|
||||
MT EUR 978 2
|
||||
MH USD 840 2
|
||||
MQ EUR 978 2
|
||||
MR MRO 478 2
|
||||
MR MRU 929 2
|
||||
MU MUR 480 2
|
||||
YT EUR 978 2
|
||||
MX MXN 484 2
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,9 +23,9 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8040211 8191404
|
||||
* @summary Checks the IANA language subtag registry data updation
|
||||
* (LSR Revision: 2017-08-15) with Locale and Locale.LanguageRange
|
||||
* @bug 8040211 8191404 8203872
|
||||
* @summary Checks the IANA language subtag registry data update
|
||||
* (LSR Revision: 2018-04-23) with Locale and Locale.LanguageRange
|
||||
* class methods.
|
||||
* @run main Bug8040211
|
||||
*/
|
||||
@ -67,8 +67,8 @@ public class Bug8040211 {
|
||||
private static void test_parse() {
|
||||
boolean error = false;
|
||||
String str = "Accept-Language: aam, adp, aue, bcg, cqu, ema,"
|
||||
+ " en-gb-oed, gti, koj, kwq, kxe, lii, lmm, mtm, ngv,"
|
||||
+ " oyb, phr, pub, suj, taj;q=0.9, yug;q=0.5, gfx;q=0.4";
|
||||
+ " en-gb-oed, gti, kdz, koj, kwq, kxe, lii, lmm, mtm, ngv,"
|
||||
+ " oyb, phr, pub, suj, taj;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4";
|
||||
ArrayList<LanguageRange> expected = new ArrayList<>();
|
||||
expected.add(new LanguageRange("aam", 1.0));
|
||||
expected.add(new LanguageRange("aas", 1.0));
|
||||
@ -86,6 +86,8 @@ public class Bug8040211 {
|
||||
expected.add(new LanguageRange("en-gb-oxendict", 1.0));
|
||||
expected.add(new LanguageRange("gti", 1.0));
|
||||
expected.add(new LanguageRange("nyc", 1.0));
|
||||
expected.add(new LanguageRange("kdz", 1.0));
|
||||
expected.add(new LanguageRange("ncp", 1.0));
|
||||
expected.add(new LanguageRange("koj", 1.0));
|
||||
expected.add(new LanguageRange("kwv", 1.0));
|
||||
expected.add(new LanguageRange("kwq", 1.0));
|
||||
@ -112,6 +114,8 @@ public class Bug8040211 {
|
||||
expected.add(new LanguageRange("xsj", 1.0));
|
||||
expected.add(new LanguageRange("taj", 0.9));
|
||||
expected.add(new LanguageRange("tsf", 0.9));
|
||||
expected.add(new LanguageRange("ar-hyw", 0.8));
|
||||
expected.add(new LanguageRange("ar-arevmda", 0.8));
|
||||
expected.add(new LanguageRange("yug", 0.5));
|
||||
expected.add(new LanguageRange("yuu", 0.5));
|
||||
expected.add(new LanguageRange("gfx", 0.4));
|
||||
@ -176,15 +180,15 @@ public class Bug8040211 {
|
||||
private static void test_filter() {
|
||||
boolean error = false;
|
||||
|
||||
String ranges = "mtm-RU, en-gb-oed, coy";
|
||||
String tags = "de-DE, en, mtm-RU, ymt-RU, en-gb-oxendict, ja-JP, pij, nts";
|
||||
String ranges = "mtm-RU, en-gb-oed, coy, ar-HY";
|
||||
String tags = "de-DE, en, mtm-RU, ymt-RU, en-gb-oxendict, ja-JP, pij, nts, ar-arevela";
|
||||
FilteringMode mode = EXTENDED_FILTERING;
|
||||
|
||||
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
|
||||
List<Locale> tagList = generateLocales(tags);
|
||||
String actualLocales
|
||||
= showLocales(Locale.filter(priorityList, tagList, mode));
|
||||
String expectedLocales = "mtm-RU, ymt-RU, en-GB-oxendict, nts, pij";
|
||||
String expectedLocales = "mtm-RU, ymt-RU, en-GB-oxendict, nts, pij, ar-arevela";
|
||||
|
||||
if (!expectedLocales.equals(actualLocales)) {
|
||||
error = true;
|
||||
|
||||
123
test/jdk/java/util/jar/Attributes/TestAttrsNL.java
Normal file
123
test/jdk/java/util/jar/Attributes/TestAttrsNL.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8200530
|
||||
* @summary Test Attributes newline
|
||||
*/
|
||||
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Attributes.Name;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
public class TestAttrsNL {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
|
||||
String manifestStr =
|
||||
"Manifest-Version: 1.0\r\n" +
|
||||
"Created-By: 11 (Oracle Corporation)\r\n" +
|
||||
"key1: value1\r\n" +
|
||||
"key2: value2\r\n END\r\n" +
|
||||
"key3: value3\r\n \r\n" +
|
||||
"key4: value4\r\n" +
|
||||
"\r\n\r\n" +
|
||||
"Name: Hello\r\n" +
|
||||
"key11: value11\r\n" +
|
||||
"key22: value22\r\n END\r\n" +
|
||||
"key33: value33\r\n \r\n" +
|
||||
"key44: value44\r\n";
|
||||
|
||||
Map<Name, String> mainAttrsExped = Map.of(
|
||||
new Name("Manifest-Version"), "1.0",
|
||||
new Name("Created-By"), "11 (Oracle Corporation)",
|
||||
new Name("key1"), "value1",
|
||||
new Name("key2"), "value2END",
|
||||
new Name("key3"), "value3",
|
||||
new Name("key4"), "value4"
|
||||
);
|
||||
|
||||
Map<Name, String> attrsExped = Map.of(
|
||||
new Name("key11"), "value11",
|
||||
new Name("key22"), "value22END",
|
||||
new Name("key33"), "value33",
|
||||
new Name("key44"), "value44"
|
||||
);
|
||||
|
||||
test(new Manifest(new ByteArrayInputStream(manifestStr.getBytes(UTF_8))),
|
||||
mainAttrsExped, attrsExped);
|
||||
|
||||
test(new Manifest(new ByteArrayInputStream(
|
||||
manifestStr.replaceAll("\r\n", "\r").getBytes(UTF_8))),
|
||||
mainAttrsExped, attrsExped);
|
||||
|
||||
test(new Manifest(new ByteArrayInputStream(
|
||||
manifestStr.replaceAll("\r\n", "\n").getBytes(UTF_8))),
|
||||
mainAttrsExped, attrsExped);
|
||||
|
||||
// mixed
|
||||
manifestStr =
|
||||
"Manifest-Version: 1.0\r\n" +
|
||||
"Created-By: 11 (Oracle Corporation)\n" +
|
||||
"key1: value1\r" +
|
||||
"key2: value2\r\n END\r" +
|
||||
"key3: value3\n \r\n" +
|
||||
"key4: value4\r" +
|
||||
"\r\n\n" +
|
||||
"Name: Hello\r\n" +
|
||||
"key11: value11\r" +
|
||||
"key22: value22\n END\r\n" +
|
||||
"key33: value33\r \n" +
|
||||
"key44: value44\n";
|
||||
test(new Manifest(new ByteArrayInputStream(manifestStr.getBytes(UTF_8))),
|
||||
mainAttrsExped, attrsExped);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void test(Manifest m,
|
||||
Map<Name, String> mainAttrsExped,
|
||||
Map<Name, String> attrsExped) {
|
||||
Attributes mainAttrs = m.getMainAttributes();
|
||||
mainAttrsExped.forEach( (k, v) -> {
|
||||
if (!mainAttrs.containsKey(k) || !mainAttrs.get(k).equals(v)) {
|
||||
System.out.printf(" containsKey(%s) : %b%n", k, mainAttrs.containsKey(k));
|
||||
System.out.printf(" get(%s) : %s%n", k, mainAttrs.get(k));
|
||||
throw new RuntimeException("expected attr: k=<" + k + ">, v=<" + v + ">");
|
||||
}
|
||||
});
|
||||
|
||||
Attributes attrs = m.getAttributes("Hello");
|
||||
attrs.forEach( (k, v) -> {
|
||||
if (!attrs.containsKey(k) || !attrs.get(k).equals(v)) {
|
||||
System.out.printf(" containsKey(%s) : %b%n", k, attrs.containsKey(k));
|
||||
System.out.printf(" get(%s) : %s%n", k, attrs.get(k));
|
||||
throw new RuntimeException("expected attr: k=<" + k + ">, v=<" + v + ">");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,8 +22,8 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8185582
|
||||
* @modules java.base/java.util.zip:open
|
||||
* @bug 8185582 8197989
|
||||
* @modules java.base/java.util.zip:open java.base/jdk.internal.vm.annotation
|
||||
* @summary Check the resources of Inflater, Deflater and ZipFile are always
|
||||
* cleaned/released when the instance is not unreachable
|
||||
*/
|
||||
@ -34,6 +34,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.zip.*;
|
||||
import jdk.internal.vm.annotation.DontInline;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
public class TestCleaner {
|
||||
@ -163,10 +164,8 @@ public class TestCleaner {
|
||||
}
|
||||
}
|
||||
|
||||
private static void testZipFile() throws Throwable {
|
||||
File dir = new File(System.getProperty("test.dir", "."));
|
||||
File zip = File.createTempFile("testzf", "zip", dir);
|
||||
Object zsrc = null;
|
||||
@DontInline
|
||||
private static Object openAndCloseZipFile(File zip) throws Throwable {
|
||||
try {
|
||||
try (var fos = new FileOutputStream(zip);
|
||||
var zos = new ZipOutputStream(fos)) {
|
||||
@ -193,12 +192,39 @@ public class TestCleaner {
|
||||
if (!fieldZsrc.trySetAccessible()) {
|
||||
throw new RuntimeException("'ZipFile.zsrc' is not accesible");
|
||||
}
|
||||
zsrc = fieldZsrc.get(zfRes);
|
||||
|
||||
return fieldZsrc.get(zfRes);
|
||||
} finally {
|
||||
zip.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@DontInline
|
||||
private static void openAndCloseSubZipFile(File zip, CountDownLatch closeCountDown)
|
||||
throws Throwable {
|
||||
try {
|
||||
try (var fos = new FileOutputStream(zip);
|
||||
var zos = new ZipOutputStream(fos)) {
|
||||
zos.putNextEntry(new ZipEntry("hello"));
|
||||
zos.write("hello".getBytes(US_ASCII));
|
||||
zos.closeEntry();
|
||||
}
|
||||
var zf = new SubclassedZipFile(zip, closeCountDown);
|
||||
var es = zf.entries();
|
||||
while (es.hasMoreElements()) {
|
||||
zf.getInputStream(es.nextElement()).read();
|
||||
}
|
||||
es = null;
|
||||
zf = null;
|
||||
} finally {
|
||||
zip.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testZipFile() throws Throwable {
|
||||
File dir = new File(System.getProperty("test.dir", "."));
|
||||
File zip = File.createTempFile("testzf", "zip", dir);
|
||||
|
||||
Object zsrc = openAndCloseZipFile(zip);
|
||||
if (zsrc != null) {
|
||||
Field zfileField = zsrc.getClass().getDeclaredField("zfile");
|
||||
if (!zfileField.trySetAccessible()) {
|
||||
@ -219,23 +245,7 @@ public class TestCleaner {
|
||||
// test subclassed ZipFile, for behavioral compatibility.
|
||||
// should be removed if the finalize() method is finally removed.
|
||||
var closeCountDown = new CountDownLatch(1);
|
||||
try {
|
||||
try (var fos = new FileOutputStream(zip);
|
||||
var zos = new ZipOutputStream(fos)) {
|
||||
zos.putNextEntry(new ZipEntry("hello"));
|
||||
zos.write("hello".getBytes(US_ASCII));
|
||||
zos.closeEntry();
|
||||
}
|
||||
var zf = new SubclassedZipFile(zip, closeCountDown);
|
||||
var es = zf.entries();
|
||||
while (es.hasMoreElements()) {
|
||||
zf.getInputStream(es.nextElement()).read();
|
||||
}
|
||||
es = null;
|
||||
zf = null;
|
||||
} finally {
|
||||
zip.delete();
|
||||
}
|
||||
openAndCloseSubZipFile(zip, closeCountDown);
|
||||
while (!closeCountDown.await(10, TimeUnit.MILLISECONDS)) {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
@ -8317,3 +8317,6 @@ CurrencyNames//stn=S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra
|
||||
CurrencyNames//lak=Lao Kip
|
||||
CurrencyNames//php=Philippine Piso
|
||||
CurrencyNames//azn=Azerbaijan Manat
|
||||
|
||||
# bug $8193552
|
||||
CurrencyNames//mru=Mauritanian Ouguiya
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
* 7114053 7074882 7040556 8008577 8013836 8021121 6192407 6931564 8027695
|
||||
* 8017142 8037343 8055222 8042126 8074791 8075173 8080774 8129361 8134916
|
||||
* 8145136 8145952 8164784 8037111 8081643 7037368 8178872 8185841 8190918
|
||||
* 8187946 8195478 8181157 8179071
|
||||
* 8187946 8195478 8181157 8179071 8193552 8202026 8204269
|
||||
* @summary Verify locale data
|
||||
* @modules java.base/sun.util.resources
|
||||
* @modules jdk.localedata
|
||||
|
||||
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8190875
|
||||
* @summary modules not listed in overview/index page
|
||||
* @library /tools/lib ../lib
|
||||
* @modules
|
||||
* jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @build JavadocTester
|
||||
* @run main TestIndexWithModules
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import builder.ClassBuilder;
|
||||
import toolbox.ModuleBuilder;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
|
||||
public class TestIndexWithModules extends JavadocTester {
|
||||
|
||||
final ToolBox tb;
|
||||
private final Path src;
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
TestIndexWithModules tester = new TestIndexWithModules();
|
||||
tester.runTests(m -> new Object[]{Paths.get(m.getName())});
|
||||
}
|
||||
|
||||
TestIndexWithModules() throws Exception{
|
||||
tb = new ToolBox();
|
||||
src = Paths.get("src");
|
||||
initModules();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexWithOverviewPath(Path base) throws Exception {
|
||||
Path out = base.resolve("out");
|
||||
|
||||
tb.writeFile("overview.html",
|
||||
"<html><body>The overview summary page header</body></html>");
|
||||
|
||||
javadoc("-d", out.toString(),
|
||||
"-overview", "overview.html",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m1");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkOrder("index.html",
|
||||
"The overview summary page header",
|
||||
"Modules",
|
||||
"<a href=\"m1/module-summary.html\">m1</a>");
|
||||
|
||||
}
|
||||
|
||||
//multiple modules with frames
|
||||
@Test
|
||||
void testIndexWithMultipleModules1(Path base) throws Exception {
|
||||
Path out = base.resolve("out");
|
||||
javadoc("-d", out.toString(),
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m1,m3,m4",
|
||||
"--frames");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("index.html", true,
|
||||
"window.location.replace('overview-summary.html')");
|
||||
checkOrder("overview-summary.html",
|
||||
"Modules",
|
||||
"<a href=\"m1/module-summary.html\">m1</a>",
|
||||
"<a href=\"m3/module-summary.html\">m3</a>",
|
||||
"<a href=\"m4/module-summary.html\">m4</a>");
|
||||
}
|
||||
|
||||
//multiple modules with out frames
|
||||
@Test
|
||||
void testIndexWithMultipleModules2(Path base) throws Exception {
|
||||
Path out = base.resolve("out");
|
||||
javadoc("-d", out.toString(),
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m1,m3,m4",
|
||||
"--no-frames");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkOrder("index.html",
|
||||
"Modules",
|
||||
"<a href=\"m1/module-summary.html\">m1</a>",
|
||||
"<a href=\"m3/module-summary.html\">m3</a>",
|
||||
"<a href=\"m4/module-summary.html\">m4</a>");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexWithSingleModule(Path base) throws Exception {
|
||||
Path out = base.resolve("out");
|
||||
javadoc("-d", out.toString(),
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m2");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkOutput("index.html", true,
|
||||
"window.location.replace('m2/module-summary.html')");
|
||||
}
|
||||
|
||||
//no modules and multiple packages
|
||||
@Test
|
||||
void testIndexWithNoModules1(Path base) throws Exception{
|
||||
Path out = base.resolve("out");
|
||||
new ClassBuilder(tb, "P1.A1")
|
||||
.setModifiers("public","class")
|
||||
.write(src);
|
||||
|
||||
new ClassBuilder(tb, "P2.A2")
|
||||
.setModifiers("public","class")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", out.toString(),
|
||||
"--no-frames",
|
||||
"-sourcepath", src.toString(),
|
||||
"P1","P2");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkOrder("index.html",
|
||||
"Packages",
|
||||
"<a href=\"P1/package-summary.html\">P1</a>",
|
||||
"<a href=\"P2/package-summary.html\">P2</a>");
|
||||
|
||||
}
|
||||
|
||||
//no modules and one package
|
||||
@Test
|
||||
void testIndexWithNoModules2(Path base) throws Exception{
|
||||
Path out = base.resolve("out");
|
||||
new ClassBuilder(tb, "P1.A1")
|
||||
.setModifiers("public","class")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", out.toString(),
|
||||
"--no-frames",
|
||||
"-sourcepath", src.toString(),
|
||||
"P1");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkOrder("index.html",
|
||||
"window.location.replace('P1/package-summary.html')");
|
||||
}
|
||||
|
||||
void initModules() throws Exception {
|
||||
new ModuleBuilder(tb, "m1")
|
||||
.exports("p1")
|
||||
.classes("package p1; public class c1{}")
|
||||
.write(src);
|
||||
|
||||
new ModuleBuilder(tb, "m2")
|
||||
.exports("p1")
|
||||
.exports("p2")
|
||||
.classes("package p1; public class c1{}")
|
||||
.classes("package p2; public class c2{}")
|
||||
.write(src);
|
||||
|
||||
new ModuleBuilder(tb, "m3").write(src);
|
||||
|
||||
new ModuleBuilder(tb, "m4").write(src);
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@
|
||||
* @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363
|
||||
* 8168766 8168688 8162674 8160196 8175799 8174974 8176778 8177562 8175218
|
||||
* 8175823 8166306 8178043 8181622 8183511 8169819 8074407 8183037 8191464
|
||||
8164407 8192007 8182765 8196200 8196201 8196202
|
||||
8164407 8192007 8182765 8196200 8196201 8196202 8196202
|
||||
* @summary Test modules support in javadoc.
|
||||
* @author bpatel
|
||||
* @library ../lib
|
||||
@ -1574,23 +1574,13 @@ public class TestModules extends JavadocTester {
|
||||
}
|
||||
|
||||
void checkGroupOptionSingleModule() {
|
||||
checkOutput("overview-summary.html", true,
|
||||
"<div class=\"contentContainer\">\n"
|
||||
+ "<table class=\"overviewSummary\">\n"
|
||||
+ "<caption><span>Module Group B</span><span class=\"tabEnd\"> </span></caption>");
|
||||
checkOutput("overview-summary.html", false,
|
||||
"<table class=\"overviewSummary\">\n"
|
||||
+ "<caption><span>Modules</span><span class=\"tabEnd\"> </span></caption>");
|
||||
checkOutput("index.html", true,
|
||||
"window.location.replace('moduleB/module-summary.html')");
|
||||
}
|
||||
|
||||
void checkGroupOptionSingleModule_html4() {
|
||||
checkOutput("overview-summary.html", true,
|
||||
"<div class=\"contentContainer\">\n"
|
||||
+ "<table class=\"overviewSummary\" summary=\"Module Summary table, listing modules, and an explanation\">\n"
|
||||
+ "<caption><span>Module Group B</span><span class=\"tabEnd\"> </span></caption>");
|
||||
checkOutput("overview-summary.html", false,
|
||||
"<table class=\"overviewSummary\" summary=\"Module Summary table, listing modules, and an explanation\">\n"
|
||||
+ "<caption><span>Modules</span><span class=\"tabEnd\"> </span></caption>");
|
||||
checkOutput("index.html", true,
|
||||
"window.location.replace('moduleB/module-summary.html')");
|
||||
}
|
||||
|
||||
void checkModuleName(boolean found) {
|
||||
|
||||
@ -399,7 +399,7 @@ public class TestSearch extends JavadocTester {
|
||||
"<!--[if IE]>\n",
|
||||
"<script type=\"text/javascript\" src=\"jquery/jszip-utils/dist/jszip-utils-ie.min.js\"></script>\n",
|
||||
"<![endif]-->\n",
|
||||
"<script type=\"text/javascript\" src=\"jquery/jquery-1.10.2.js\"></script>\n",
|
||||
"<script type=\"text/javascript\" src=\"jquery/jquery-1.12.4.js\"></script>\n",
|
||||
"<script type=\"text/javascript\" src=\"jquery/jquery-ui.js\"></script>",
|
||||
"var pathtoroot = \"./\";\n"
|
||||
+ "var useModuleDirectories = " + moduleDirectoriesVar + ";\n"
|
||||
@ -591,7 +591,7 @@ public class TestSearch extends JavadocTester {
|
||||
void checkJqueryAndImageFiles(boolean expectedOutput) {
|
||||
checkFiles(expectedOutput,
|
||||
"search.js",
|
||||
"jquery/jquery-1.10.2.js",
|
||||
"jquery/jquery-1.12.4.js",
|
||||
"jquery/jquery-ui.js",
|
||||
"jquery/jquery-ui.css",
|
||||
"jquery/jquery-ui.min.js",
|
||||
|
||||
@ -198,7 +198,7 @@ class APITest {
|
||||
"help-doc.html",
|
||||
"index-all.html",
|
||||
"index.html",
|
||||
"jquery/jquery-1.10.2.js",
|
||||
"jquery/jquery-1.12.4.js",
|
||||
"jquery/jquery-ui.js",
|
||||
"jquery/jquery-ui.css",
|
||||
"jquery/jquery-ui.min.js",
|
||||
|
||||
@ -198,7 +198,7 @@ class APITest {
|
||||
"help-doc.html",
|
||||
"index-all.html",
|
||||
"index.html",
|
||||
"jquery/jquery-1.10.2.js",
|
||||
"jquery/jquery-1.12.4.js",
|
||||
"jquery/jquery-ui.js",
|
||||
"jquery/jquery-ui.css",
|
||||
"jquery/jquery-ui.min.js",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user